Update deps
This commit is contained in:
parent
f6f63743ce
commit
9e7221c31c
4
go.mod
4
go.mod
|
@ -21,8 +21,8 @@ require (
|
|||
github.com/miekg/dns v1.1.43
|
||||
github.com/powerman/check v1.6.0
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519
|
||||
golang.org/x/net v0.0.0-20211008194852-3b03d305991f
|
||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac
|
||||
golang.org/x/net v0.0.0-20211104170005-ce137452f963
|
||||
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0
|
||||
)
|
||||
|
||||
|
|
10
go.sum
10
go.sum
|
@ -359,8 +359,6 @@ github.com/jedisct1/go-dnsstamps v0.0.0-20210810213811-61cc83d2a354 h1:sIB9mDh2s
|
|||
github.com/jedisct1/go-dnsstamps v0.0.0-20210810213811-61cc83d2a354/go.mod h1:t35n6rsPE3nD3RXbc5hI5Ax1ci/SSYTpx0BdMXh/1aE=
|
||||
github.com/jedisct1/go-hpke-compact v0.0.0-20210930135406-0763750339f0 h1:RHAwzltAHFehEX1xUamZQtmWYflYReGY7jvmRZ3v7QU=
|
||||
github.com/jedisct1/go-hpke-compact v0.0.0-20210930135406-0763750339f0/go.mod h1:wDWQCpgsVR2M5u//vKIwqBZdbsS/f/rZiOuJPaFSkmk=
|
||||
github.com/jedisct1/go-minisign v0.0.0-20211008170404-d0c644b276f4 h1:kQYxZWkRu2ax22QivreeQ72p/FsfXN5D5LFLbfZGuFw=
|
||||
github.com/jedisct1/go-minisign v0.0.0-20211008170404-d0c644b276f4/go.mod h1:hQmNrgofl+IY/8L+n20H6E6PWBBTokdsv+q49j0QhsU=
|
||||
github.com/jedisct1/go-minisign v0.0.0-20211028175153-1c139d1cc84b h1:ZGiXF8sz7PDk6RgkP+A/SFfUD0ZR/AgG6SpRNEDKZy8=
|
||||
github.com/jedisct1/go-minisign v0.0.0-20211028175153-1c139d1cc84b/go.mod h1:hQmNrgofl+IY/8L+n20H6E6PWBBTokdsv+q49j0QhsU=
|
||||
github.com/jedisct1/xsecretbox v0.0.0-20210927135450-ebe41aef7bef h1:1Jom8JnCkrgivikTdt0lg5lHpZRvpP98hn8H1bIjFLk=
|
||||
|
@ -802,8 +800,8 @@ golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwY
|
|||
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20211008194852-3b03d305991f h1:1scJEYZBaF48BaG6tYbtxmLcXqwYGSfGcMoStTqkkIw=
|
||||
golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211104170005-ce137452f963 h1:8gJUadZl+kWvZBqG/LautX0X6qe5qTC2VI/3V3NBRAY=
|
||||
golang.org/x/net v0.0.0-20211104170005-ce137452f963/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
|
@ -880,8 +878,8 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac h1:oN6lz7iLW/YC7un8pq+9bOLyXrprv2+DKfkJY+2LJJw=
|
||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b h1:1VkfZQv42XQlA/jchYumAnv1UPo6RgF9rJFkTgZIxO4=
|
||||
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
|
|
@ -140,25 +140,29 @@ func buildRootHuffmanNode() {
|
|||
panic("unexpected size")
|
||||
}
|
||||
lazyRootHuffmanNode = newInternalNode()
|
||||
for i, code := range huffmanCodes {
|
||||
addDecoderNode(byte(i), code, huffmanCodeLen[i])
|
||||
}
|
||||
}
|
||||
// allocate a leaf node for each of the 256 symbols
|
||||
leaves := new([256]node)
|
||||
|
||||
func addDecoderNode(sym byte, code uint32, codeLen uint8) {
|
||||
cur := lazyRootHuffmanNode
|
||||
for codeLen > 8 {
|
||||
codeLen -= 8
|
||||
i := uint8(code >> codeLen)
|
||||
if cur.children[i] == nil {
|
||||
cur.children[i] = newInternalNode()
|
||||
for sym, code := range huffmanCodes {
|
||||
codeLen := huffmanCodeLen[sym]
|
||||
|
||||
cur := lazyRootHuffmanNode
|
||||
for codeLen > 8 {
|
||||
codeLen -= 8
|
||||
i := uint8(code >> codeLen)
|
||||
if cur.children[i] == nil {
|
||||
cur.children[i] = newInternalNode()
|
||||
}
|
||||
cur = cur.children[i]
|
||||
}
|
||||
shift := 8 - codeLen
|
||||
start, end := int(uint8(code<<shift)), int(1<<shift)
|
||||
|
||||
leaves[sym].sym = byte(sym)
|
||||
leaves[sym].codeLen = codeLen
|
||||
for i := start; i < start+end; i++ {
|
||||
cur.children[i] = &leaves[sym]
|
||||
}
|
||||
cur = cur.children[i]
|
||||
}
|
||||
shift := 8 - codeLen
|
||||
start, end := int(uint8(code<<shift)), int(1<<shift)
|
||||
for i := start; i < start+end; i++ {
|
||||
cur.children[i] = &node{sym: sym, codeLen: codeLen}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ import (
|
|||
"net/http"
|
||||
"net/http/httptrace"
|
||||
"net/textproto"
|
||||
"os"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -130,6 +131,11 @@ type Transport struct {
|
|||
// Defaults to 15s.
|
||||
PingTimeout time.Duration
|
||||
|
||||
// WriteByteTimeout is the timeout after which the connection will be
|
||||
// closed no data can be written to it. The timeout begins when data is
|
||||
// available to write, and is extended whenever any bytes are written.
|
||||
WriteByteTimeout time.Duration
|
||||
|
||||
// CountError, if non-nil, is called on HTTP/2 transport errors.
|
||||
// It's intended to increment a metric for monitoring, such
|
||||
// as an expvar or Prometheus metric.
|
||||
|
@ -300,12 +306,17 @@ type ClientConn struct {
|
|||
// clientStream is the state for a single HTTP/2 stream. One of these
|
||||
// is created for each Transport.RoundTrip call.
|
||||
type clientStream struct {
|
||||
cc *ClientConn
|
||||
req *http.Request
|
||||
cc *ClientConn
|
||||
|
||||
// Fields of Request that we may access even after the response body is closed.
|
||||
ctx context.Context
|
||||
reqCancel <-chan struct{}
|
||||
|
||||
trace *httptrace.ClientTrace // or nil
|
||||
ID uint32
|
||||
bufPipe pipe // buffered pipe with the flow-controlled response payload
|
||||
requestedGzip bool
|
||||
isHead bool
|
||||
|
||||
abortOnce sync.Once
|
||||
abort chan struct{} // closed to signal stream should end immediately
|
||||
|
@ -322,7 +333,10 @@ type clientStream struct {
|
|||
inflow flow // guarded by cc.mu
|
||||
bytesRemain int64 // -1 means unknown; owned by transportResponseBody.Read
|
||||
readErr error // sticky read error; owned by transportResponseBody.Read
|
||||
stopReqBody error // if non-nil, stop writing req body; guarded by cc.mu
|
||||
|
||||
reqBody io.ReadCloser
|
||||
reqBodyContentLength int64 // -1 means unknown
|
||||
reqBodyClosed bool // body has been closed; guarded by cc.mu
|
||||
|
||||
// owned by writeRequest:
|
||||
sentEndStream bool // sent an END_STREAM flag to the peer
|
||||
|
@ -362,6 +376,10 @@ func (cs *clientStream) abortStreamLocked(err error) {
|
|||
cs.abortErr = err
|
||||
close(cs.abort)
|
||||
})
|
||||
if cs.reqBody != nil && !cs.reqBodyClosed {
|
||||
cs.reqBody.Close()
|
||||
cs.reqBodyClosed = true
|
||||
}
|
||||
// TODO(dneil): Clean up tests where cs.cc.cond is nil.
|
||||
if cs.cc.cond != nil {
|
||||
// Wake up writeRequestBody if it is waiting on flow control.
|
||||
|
@ -369,31 +387,43 @@ func (cs *clientStream) abortStreamLocked(err error) {
|
|||
}
|
||||
}
|
||||
|
||||
func (cs *clientStream) abortRequestBodyWrite(err error) {
|
||||
if err == nil {
|
||||
panic("nil error")
|
||||
}
|
||||
func (cs *clientStream) abortRequestBodyWrite() {
|
||||
cc := cs.cc
|
||||
cc.mu.Lock()
|
||||
if cs.stopReqBody == nil {
|
||||
cs.stopReqBody = err
|
||||
defer cc.mu.Unlock()
|
||||
if cs.reqBody != nil && !cs.reqBodyClosed {
|
||||
cs.reqBody.Close()
|
||||
cs.reqBodyClosed = true
|
||||
cc.cond.Broadcast()
|
||||
}
|
||||
cc.mu.Unlock()
|
||||
}
|
||||
|
||||
type stickyErrWriter struct {
|
||||
w io.Writer
|
||||
err *error
|
||||
conn net.Conn
|
||||
timeout time.Duration
|
||||
err *error
|
||||
}
|
||||
|
||||
func (sew stickyErrWriter) Write(p []byte) (n int, err error) {
|
||||
if *sew.err != nil {
|
||||
return 0, *sew.err
|
||||
}
|
||||
n, err = sew.w.Write(p)
|
||||
*sew.err = err
|
||||
return
|
||||
for {
|
||||
if sew.timeout != 0 {
|
||||
sew.conn.SetWriteDeadline(time.Now().Add(sew.timeout))
|
||||
}
|
||||
nn, err := sew.conn.Write(p[n:])
|
||||
n += nn
|
||||
if n < len(p) && nn > 0 && errors.Is(err, os.ErrDeadlineExceeded) {
|
||||
// Keep extending the deadline so long as we're making progress.
|
||||
continue
|
||||
}
|
||||
if sew.timeout != 0 {
|
||||
sew.conn.SetWriteDeadline(time.Time{})
|
||||
}
|
||||
*sew.err = err
|
||||
return n, err
|
||||
}
|
||||
}
|
||||
|
||||
// noCachedConnError is the concrete type of ErrNoCachedConn, which
|
||||
|
@ -648,7 +678,11 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro
|
|||
|
||||
// TODO: adjust this writer size to account for frame size +
|
||||
// MTU + crypto/tls record padding.
|
||||
cc.bw = bufio.NewWriter(stickyErrWriter{c, &cc.werr})
|
||||
cc.bw = bufio.NewWriter(stickyErrWriter{
|
||||
conn: c,
|
||||
timeout: t.WriteByteTimeout,
|
||||
err: &cc.werr,
|
||||
})
|
||||
cc.br = bufio.NewReader(c)
|
||||
cc.fr = NewFramer(cc.bw, cc.br)
|
||||
if t.CountError != nil {
|
||||
|
@ -1065,15 +1099,19 @@ func (cc *ClientConn) decrStreamReservationsLocked() {
|
|||
func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
ctx := req.Context()
|
||||
cs := &clientStream{
|
||||
cc: cc,
|
||||
req: req,
|
||||
trace: httptrace.ContextClientTrace(req.Context()),
|
||||
peerClosed: make(chan struct{}),
|
||||
abort: make(chan struct{}),
|
||||
respHeaderRecv: make(chan struct{}),
|
||||
donec: make(chan struct{}),
|
||||
cc: cc,
|
||||
ctx: ctx,
|
||||
reqCancel: req.Cancel,
|
||||
isHead: req.Method == "HEAD",
|
||||
reqBody: req.Body,
|
||||
reqBodyContentLength: actualContentLength(req),
|
||||
trace: httptrace.ContextClientTrace(ctx),
|
||||
peerClosed: make(chan struct{}),
|
||||
abort: make(chan struct{}),
|
||||
respHeaderRecv: make(chan struct{}),
|
||||
donec: make(chan struct{}),
|
||||
}
|
||||
go cs.doRequest()
|
||||
go cs.doRequest(req)
|
||||
|
||||
waitDone := func() error {
|
||||
select {
|
||||
|
@ -1081,7 +1119,7 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) {
|
|||
return nil
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case <-req.Cancel:
|
||||
case <-cs.reqCancel:
|
||||
return errRequestCanceled
|
||||
}
|
||||
}
|
||||
|
@ -1100,7 +1138,7 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) {
|
|||
// doesn't, they'll RST_STREAM us soon enough. This is a
|
||||
// heuristic to avoid adding knobs to Transport. Hopefully
|
||||
// we can keep it.
|
||||
cs.abortRequestBodyWrite(errStopReqBodyWrite)
|
||||
cs.abortRequestBodyWrite()
|
||||
}
|
||||
res.Request = req
|
||||
res.TLS = cc.tlsState
|
||||
|
@ -1117,8 +1155,11 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) {
|
|||
waitDone()
|
||||
return nil, cs.abortErr
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
case <-req.Cancel:
|
||||
err := ctx.Err()
|
||||
cs.abortStream(err)
|
||||
return nil, err
|
||||
case <-cs.reqCancel:
|
||||
cs.abortStream(errRequestCanceled)
|
||||
return nil, errRequestCanceled
|
||||
}
|
||||
}
|
||||
|
@ -1127,8 +1168,8 @@ func (cc *ClientConn) RoundTrip(req *http.Request) (*http.Response, error) {
|
|||
// doRequest runs for the duration of the request lifetime.
|
||||
//
|
||||
// It sends the request and performs post-request cleanup (closing Request.Body, etc.).
|
||||
func (cs *clientStream) doRequest() {
|
||||
err := cs.writeRequest()
|
||||
func (cs *clientStream) doRequest(req *http.Request) {
|
||||
err := cs.writeRequest(req)
|
||||
cs.cleanupWriteRequest(err)
|
||||
}
|
||||
|
||||
|
@ -1139,12 +1180,11 @@ func (cs *clientStream) doRequest() {
|
|||
//
|
||||
// It returns non-nil if the request ends otherwise.
|
||||
// If the returned error is StreamError, the error Code may be used in resetting the stream.
|
||||
func (cs *clientStream) writeRequest() (err error) {
|
||||
func (cs *clientStream) writeRequest(req *http.Request) (err error) {
|
||||
cc := cs.cc
|
||||
req := cs.req
|
||||
ctx := req.Context()
|
||||
ctx := cs.ctx
|
||||
|
||||
if err := checkConnHeaders(cs.req); err != nil {
|
||||
if err := checkConnHeaders(req); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -1156,7 +1196,7 @@ func (cs *clientStream) writeRequest() (err error) {
|
|||
}
|
||||
select {
|
||||
case cc.reqHeaderMu <- struct{}{}:
|
||||
case <-req.Cancel:
|
||||
case <-cs.reqCancel:
|
||||
return errRequestCanceled
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
|
@ -1179,7 +1219,7 @@ func (cs *clientStream) writeRequest() (err error) {
|
|||
if !cc.t.disableCompression() &&
|
||||
req.Header.Get("Accept-Encoding") == "" &&
|
||||
req.Header.Get("Range") == "" &&
|
||||
req.Method != "HEAD" {
|
||||
!cs.isHead {
|
||||
// Request gzip only, not deflate. Deflate is ambiguous and
|
||||
// not as universally supported anyway.
|
||||
// See: https://zlib.net/zlib_faq.html#faq39
|
||||
|
@ -1198,19 +1238,23 @@ func (cs *clientStream) writeRequest() (err error) {
|
|||
continueTimeout := cc.t.expectContinueTimeout()
|
||||
if continueTimeout != 0 &&
|
||||
!httpguts.HeaderValuesContainsToken(
|
||||
cs.req.Header["Expect"],
|
||||
req.Header["Expect"],
|
||||
"100-continue") {
|
||||
continueTimeout = 0
|
||||
cs.on100 = make(chan struct{}, 1)
|
||||
}
|
||||
|
||||
err = cs.encodeAndWriteHeaders()
|
||||
// Past this point (where we send request headers), it is possible for
|
||||
// RoundTrip to return successfully. Since the RoundTrip contract permits
|
||||
// the caller to "mutate or reuse" the Request after closing the Response's Body,
|
||||
// we must take care when referencing the Request from here on.
|
||||
err = cs.encodeAndWriteHeaders(req)
|
||||
<-cc.reqHeaderMu
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
hasBody := actualContentLength(cs.req) != 0
|
||||
hasBody := cs.reqBodyContentLength != 0
|
||||
if !hasBody {
|
||||
cs.sentEndStream = true
|
||||
} else {
|
||||
|
@ -1226,7 +1270,7 @@ func (cs *clientStream) writeRequest() (err error) {
|
|||
err = cs.abortErr
|
||||
case <-ctx.Done():
|
||||
err = ctx.Err()
|
||||
case <-req.Cancel:
|
||||
case <-cs.reqCancel:
|
||||
err = errRequestCanceled
|
||||
}
|
||||
timer.Stop()
|
||||
|
@ -1236,7 +1280,7 @@ func (cs *clientStream) writeRequest() (err error) {
|
|||
}
|
||||
}
|
||||
|
||||
if err = cs.writeRequestBody(req.Body); err != nil {
|
||||
if err = cs.writeRequestBody(req); err != nil {
|
||||
if err != errStopReqBodyWrite {
|
||||
traceWroteRequest(cs.trace, err)
|
||||
return err
|
||||
|
@ -1271,16 +1315,15 @@ func (cs *clientStream) writeRequest() (err error) {
|
|||
return cs.abortErr
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case <-req.Cancel:
|
||||
case <-cs.reqCancel:
|
||||
return errRequestCanceled
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (cs *clientStream) encodeAndWriteHeaders() error {
|
||||
func (cs *clientStream) encodeAndWriteHeaders(req *http.Request) error {
|
||||
cc := cs.cc
|
||||
req := cs.req
|
||||
ctx := req.Context()
|
||||
ctx := cs.ctx
|
||||
|
||||
cc.wmu.Lock()
|
||||
defer cc.wmu.Unlock()
|
||||
|
@ -1291,7 +1334,7 @@ func (cs *clientStream) encodeAndWriteHeaders() error {
|
|||
return cs.abortErr
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case <-req.Cancel:
|
||||
case <-cs.reqCancel:
|
||||
return errRequestCanceled
|
||||
default:
|
||||
}
|
||||
|
@ -1301,14 +1344,14 @@ func (cs *clientStream) encodeAndWriteHeaders() error {
|
|||
// we send: HEADERS{1}, CONTINUATION{0,} + DATA{0,} (DATA is
|
||||
// sent by writeRequestBody below, along with any Trailers,
|
||||
// again in form HEADERS{1}, CONTINUATION{0,})
|
||||
trailers, err := commaSeparatedTrailers(cs.req)
|
||||
trailers, err := commaSeparatedTrailers(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
hasTrailers := trailers != ""
|
||||
contentLen := actualContentLength(cs.req)
|
||||
contentLen := actualContentLength(req)
|
||||
hasBody := contentLen != 0
|
||||
hdrs, err := cc.encodeHeaders(cs.req, cs.requestedGzip, trailers, contentLen)
|
||||
hdrs, err := cc.encodeHeaders(req, cs.requestedGzip, trailers, contentLen)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -1327,7 +1370,6 @@ func (cs *clientStream) encodeAndWriteHeaders() error {
|
|||
// cleanupWriteRequest will send a reset to the peer.
|
||||
func (cs *clientStream) cleanupWriteRequest(err error) {
|
||||
cc := cs.cc
|
||||
req := cs.req
|
||||
|
||||
if cs.ID == 0 {
|
||||
// We were canceled before creating the stream, so return our reservation.
|
||||
|
@ -1338,10 +1380,12 @@ func (cs *clientStream) cleanupWriteRequest(err error) {
|
|||
// Request.Body is closed by the Transport,
|
||||
// and in multiple cases: server replies <=299 and >299
|
||||
// while still writing request body
|
||||
if req.Body != nil {
|
||||
if e := req.Body.Close(); err == nil {
|
||||
err = e
|
||||
}
|
||||
cc.mu.Lock()
|
||||
bodyClosed := cs.reqBodyClosed
|
||||
cs.reqBodyClosed = true
|
||||
cc.mu.Unlock()
|
||||
if !bodyClosed && cs.reqBody != nil {
|
||||
cs.reqBody.Close()
|
||||
}
|
||||
|
||||
if err != nil && cs.sentEndStream {
|
||||
|
@ -1375,7 +1419,6 @@ func (cs *clientStream) cleanupWriteRequest(err error) {
|
|||
if cs.ID != 0 {
|
||||
cc.forgetStreamID(cs.ID)
|
||||
}
|
||||
close(cs.donec)
|
||||
|
||||
cc.wmu.Lock()
|
||||
werr := cc.werr
|
||||
|
@ -1383,6 +1426,8 @@ func (cs *clientStream) cleanupWriteRequest(err error) {
|
|||
if werr != nil {
|
||||
cc.Close()
|
||||
}
|
||||
|
||||
close(cs.donec)
|
||||
}
|
||||
|
||||
// awaitOpenSlotForStream waits until len(streams) < maxConcurrentStreams.
|
||||
|
@ -1456,7 +1501,7 @@ func (cs *clientStream) frameScratchBufferLen(maxFrameSize int) int {
|
|||
if n > max {
|
||||
n = max
|
||||
}
|
||||
if cl := actualContentLength(cs.req); cl != -1 && cl+1 < n {
|
||||
if cl := cs.reqBodyContentLength; cl != -1 && cl+1 < n {
|
||||
// Add an extra byte past the declared content-length to
|
||||
// give the caller's Request.Body io.Reader a chance to
|
||||
// give us more bytes than they declared, so we can catch it
|
||||
|
@ -1471,13 +1516,13 @@ func (cs *clientStream) frameScratchBufferLen(maxFrameSize int) int {
|
|||
|
||||
var bufPool sync.Pool // of *[]byte
|
||||
|
||||
func (cs *clientStream) writeRequestBody(body io.Reader) (err error) {
|
||||
func (cs *clientStream) writeRequestBody(req *http.Request) (err error) {
|
||||
cc := cs.cc
|
||||
body := cs.reqBody
|
||||
sentEnd := false // whether we sent the final DATA frame w/ END_STREAM
|
||||
|
||||
req := cs.req
|
||||
hasTrailers := req.Trailer != nil
|
||||
remainLen := actualContentLength(req)
|
||||
remainLen := cs.reqBodyContentLength
|
||||
hasContentLen := remainLen != -1
|
||||
|
||||
cc.mu.Lock()
|
||||
|
@ -1518,23 +1563,26 @@ func (cs *clientStream) writeRequestBody(body io.Reader) (err error) {
|
|||
return err
|
||||
}
|
||||
}
|
||||
if err == io.EOF {
|
||||
sawEOF = true
|
||||
err = nil
|
||||
} else if err != nil {
|
||||
return err
|
||||
if err != nil {
|
||||
cc.mu.Lock()
|
||||
bodyClosed := cs.reqBodyClosed
|
||||
cc.mu.Unlock()
|
||||
switch {
|
||||
case bodyClosed:
|
||||
return errStopReqBodyWrite
|
||||
case err == io.EOF:
|
||||
sawEOF = true
|
||||
err = nil
|
||||
default:
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
remain := buf[:n]
|
||||
for len(remain) > 0 && err == nil {
|
||||
var allowed int32
|
||||
allowed, err = cs.awaitFlowControl(len(remain))
|
||||
switch {
|
||||
case err == errStopReqBodyWrite:
|
||||
return err
|
||||
case err == errStopReqBodyWriteAndCancel:
|
||||
return err
|
||||
case err != nil:
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cc.wmu.Lock()
|
||||
|
@ -1565,16 +1613,26 @@ func (cs *clientStream) writeRequestBody(body io.Reader) (err error) {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Since the RoundTrip contract permits the caller to "mutate or reuse"
|
||||
// a request after the Response's Body is closed, verify that this hasn't
|
||||
// happened before accessing the trailers.
|
||||
cc.mu.Lock()
|
||||
trailer := req.Trailer
|
||||
err = cs.abortErr
|
||||
cc.mu.Unlock()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cc.wmu.Lock()
|
||||
defer cc.wmu.Unlock()
|
||||
var trls []byte
|
||||
if hasTrailers {
|
||||
trls, err = cc.encodeTrailers(req)
|
||||
if len(trailer) > 0 {
|
||||
trls, err = cc.encodeTrailers(trailer)
|
||||
if err != nil {
|
||||
cc.wmu.Unlock()
|
||||
return err
|
||||
}
|
||||
}
|
||||
defer cc.wmu.Unlock()
|
||||
|
||||
// Two ways to send END_STREAM: either with trailers, or
|
||||
// with an empty DATA frame.
|
||||
|
@ -1595,23 +1653,22 @@ func (cs *clientStream) writeRequestBody(body io.Reader) (err error) {
|
|||
// if the stream is dead.
|
||||
func (cs *clientStream) awaitFlowControl(maxBytes int) (taken int32, err error) {
|
||||
cc := cs.cc
|
||||
req := cs.req
|
||||
ctx := req.Context()
|
||||
ctx := cs.ctx
|
||||
cc.mu.Lock()
|
||||
defer cc.mu.Unlock()
|
||||
for {
|
||||
if cc.closed {
|
||||
return 0, errClientConnClosed
|
||||
}
|
||||
if cs.stopReqBody != nil {
|
||||
return 0, cs.stopReqBody
|
||||
if cs.reqBodyClosed {
|
||||
return 0, errStopReqBodyWrite
|
||||
}
|
||||
select {
|
||||
case <-cs.abort:
|
||||
return 0, cs.abortErr
|
||||
case <-ctx.Done():
|
||||
return 0, ctx.Err()
|
||||
case <-req.Cancel:
|
||||
case <-cs.reqCancel:
|
||||
return 0, errRequestCanceled
|
||||
default:
|
||||
}
|
||||
|
@ -1825,11 +1882,11 @@ func shouldSendReqContentLength(method string, contentLength int64) bool {
|
|||
}
|
||||
|
||||
// requires cc.wmu be held.
|
||||
func (cc *ClientConn) encodeTrailers(req *http.Request) ([]byte, error) {
|
||||
func (cc *ClientConn) encodeTrailers(trailer http.Header) ([]byte, error) {
|
||||
cc.hbuf.Reset()
|
||||
|
||||
hlSize := uint64(0)
|
||||
for k, vv := range req.Trailer {
|
||||
for k, vv := range trailer {
|
||||
for _, v := range vv {
|
||||
hf := hpack.HeaderField{Name: k, Value: v}
|
||||
hlSize += uint64(hf.Size())
|
||||
|
@ -1839,7 +1896,7 @@ func (cc *ClientConn) encodeTrailers(req *http.Request) ([]byte, error) {
|
|||
return nil, errRequestHeaderListSize
|
||||
}
|
||||
|
||||
for k, vv := range req.Trailer {
|
||||
for k, vv := range trailer {
|
||||
lowKey, ascii := asciiToLower(k)
|
||||
if !ascii {
|
||||
// Skip writing invalid headers. Per RFC 7540, Section 8.1.2, header
|
||||
|
@ -1975,7 +2032,13 @@ func (rl *clientConnReadLoop) cleanup() {
|
|||
}
|
||||
cc.closed = true
|
||||
for _, cs := range cc.streams {
|
||||
cs.abortStreamLocked(err)
|
||||
select {
|
||||
case <-cs.peerClosed:
|
||||
// The server closed the stream before closing the conn,
|
||||
// so no need to interrupt it.
|
||||
default:
|
||||
cs.abortStreamLocked(err)
|
||||
}
|
||||
}
|
||||
cc.cond.Broadcast()
|
||||
cc.mu.Unlock()
|
||||
|
@ -2217,28 +2280,35 @@ func (rl *clientConnReadLoop) handleResponse(cs *clientStream, f *MetaHeadersFra
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
streamEnded := f.StreamEnded()
|
||||
isHead := cs.req.Method == "HEAD"
|
||||
if !streamEnded || isHead {
|
||||
res.ContentLength = -1
|
||||
if clens := res.Header["Content-Length"]; len(clens) == 1 {
|
||||
if cl, err := strconv.ParseUint(clens[0], 10, 63); err == nil {
|
||||
res.ContentLength = int64(cl)
|
||||
} else {
|
||||
// TODO: care? unlike http/1, it won't mess up our framing, so it's
|
||||
// more safe smuggling-wise to ignore.
|
||||
}
|
||||
} else if len(clens) > 1 {
|
||||
res.ContentLength = -1
|
||||
if clens := res.Header["Content-Length"]; len(clens) == 1 {
|
||||
if cl, err := strconv.ParseUint(clens[0], 10, 63); err == nil {
|
||||
res.ContentLength = int64(cl)
|
||||
} else {
|
||||
// TODO: care? unlike http/1, it won't mess up our framing, so it's
|
||||
// more safe smuggling-wise to ignore.
|
||||
}
|
||||
} else if len(clens) > 1 {
|
||||
// TODO: care? unlike http/1, it won't mess up our framing, so it's
|
||||
// more safe smuggling-wise to ignore.
|
||||
} else if f.StreamEnded() && !cs.isHead {
|
||||
res.ContentLength = 0
|
||||
}
|
||||
|
||||
if streamEnded || isHead {
|
||||
if cs.isHead {
|
||||
res.Body = noBody
|
||||
return res, nil
|
||||
}
|
||||
|
||||
if f.StreamEnded() {
|
||||
if res.ContentLength > 0 {
|
||||
res.Body = missingBody{}
|
||||
} else {
|
||||
res.Body = noBody
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
cs.bufPipe.setBuffer(&dataBuffer{expected: res.ContentLength})
|
||||
cs.bytesRemain = res.ContentLength
|
||||
res.Body = transportResponseBody{cs}
|
||||
|
@ -2282,8 +2352,7 @@ func (rl *clientConnReadLoop) processTrailers(cs *clientStream, f *MetaHeadersFr
|
|||
}
|
||||
|
||||
// transportResponseBody is the concrete type of Transport.RoundTrip's
|
||||
// Response.Body. It is an io.ReadCloser. On Read, it reads from cs.body.
|
||||
// On Close it sends RST_STREAM if EOF wasn't already seen.
|
||||
// Response.Body. It is an io.ReadCloser.
|
||||
type transportResponseBody struct {
|
||||
cs *clientStream
|
||||
}
|
||||
|
@ -2366,6 +2435,8 @@ func (b transportResponseBody) Close() error {
|
|||
}
|
||||
cc.mu.Unlock()
|
||||
|
||||
// TODO(dneil): Acquiring this mutex can block indefinitely.
|
||||
// Move flow control return to a goroutine?
|
||||
cc.wmu.Lock()
|
||||
// Return connection-level flow control.
|
||||
if unread > 0 {
|
||||
|
@ -2380,9 +2451,9 @@ func (b transportResponseBody) Close() error {
|
|||
|
||||
select {
|
||||
case <-cs.donec:
|
||||
case <-cs.req.Context().Done():
|
||||
return cs.req.Context().Err()
|
||||
case <-cs.req.Cancel:
|
||||
case <-cs.ctx.Done():
|
||||
return cs.ctx.Err()
|
||||
case <-cs.reqCancel:
|
||||
return errRequestCanceled
|
||||
}
|
||||
return nil
|
||||
|
@ -2436,7 +2507,7 @@ func (rl *clientConnReadLoop) processData(f *DataFrame) error {
|
|||
return nil
|
||||
}
|
||||
if f.Length > 0 {
|
||||
if cs.req.Method == "HEAD" && len(data) > 0 {
|
||||
if cs.isHead && len(data) > 0 {
|
||||
cc.logf("protocol error: received DATA on a HEAD request")
|
||||
rl.endStreamError(cs, StreamError{
|
||||
StreamID: f.StreamID,
|
||||
|
@ -2505,6 +2576,12 @@ func (rl *clientConnReadLoop) endStream(cs *clientStream) {
|
|||
// server.go's (*stream).endStream method.
|
||||
if !cs.readClosed {
|
||||
cs.readClosed = true
|
||||
// Close cs.bufPipe and cs.peerClosed with cc.mu held to avoid a
|
||||
// race condition: The caller can read io.EOF from Response.Body
|
||||
// and close the body before we close cs.peerClosed, causing
|
||||
// cleanupWriteRequest to send a RST_STREAM.
|
||||
rl.cc.mu.Lock()
|
||||
defer rl.cc.mu.Unlock()
|
||||
cs.bufPipe.closeWithErrorAndCode(io.EOF, cs.copyTrailers)
|
||||
close(cs.peerClosed)
|
||||
}
|
||||
|
@ -2786,6 +2863,11 @@ func (t *Transport) logf(format string, args ...interface{}) {
|
|||
|
||||
var noBody io.ReadCloser = ioutil.NopCloser(bytes.NewReader(nil))
|
||||
|
||||
type missingBody struct{}
|
||||
|
||||
func (missingBody) Close() error { return nil }
|
||||
func (missingBody) Read([]byte) (int, error) { return 0, io.ErrUnexpectedEOF }
|
||||
|
||||
func strSliceContains(ss []string, s string) bool {
|
||||
for _, v := range ss {
|
||||
if v == s {
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||
|
||||
// Copyright 2021 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.
|
||||
|
||||
//go:build go1.18
|
||||
// +build go1.18
|
||||
|
||||
package idna
|
||||
|
||||
// Transitional processing is disabled by default in Go 1.18.
|
||||
// https://golang.org/issue/47510
|
||||
const transitionalLookup = false
|
|
@ -59,10 +59,10 @@ type Option func(*options)
|
|||
// Transitional sets a Profile to use the Transitional mapping as defined in UTS
|
||||
// #46. This will cause, for example, "ß" to be mapped to "ss". Using the
|
||||
// transitional mapping provides a compromise between IDNA2003 and IDNA2008
|
||||
// compatibility. It is used by most browsers when resolving domain names. This
|
||||
// compatibility. It is used by some browsers when resolving domain names. This
|
||||
// option is only meaningful if combined with MapForLookup.
|
||||
func Transitional(transitional bool) Option {
|
||||
return func(o *options) { o.transitional = true }
|
||||
return func(o *options) { o.transitional = transitional }
|
||||
}
|
||||
|
||||
// VerifyDNSLength sets whether a Profile should fail if any of the IDN parts
|
||||
|
@ -284,7 +284,7 @@ var (
|
|||
|
||||
punycode = &Profile{}
|
||||
lookup = &Profile{options{
|
||||
transitional: true,
|
||||
transitional: transitionalLookup,
|
||||
useSTD3Rules: true,
|
||||
checkHyphens: true,
|
||||
checkJoiners: true,
|
||||
|
|
|
@ -58,10 +58,10 @@ type Option func(*options)
|
|||
// Transitional sets a Profile to use the Transitional mapping as defined in UTS
|
||||
// #46. This will cause, for example, "ß" to be mapped to "ss". Using the
|
||||
// transitional mapping provides a compromise between IDNA2003 and IDNA2008
|
||||
// compatibility. It is used by most browsers when resolving domain names. This
|
||||
// compatibility. It is used by some browsers when resolving domain names. This
|
||||
// option is only meaningful if combined with MapForLookup.
|
||||
func Transitional(transitional bool) Option {
|
||||
return func(o *options) { o.transitional = true }
|
||||
return func(o *options) { o.transitional = transitional }
|
||||
}
|
||||
|
||||
// VerifyDNSLength sets whether a Profile should fail if any of the IDN parts
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT.
|
||||
|
||||
// Copyright 2021 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.
|
||||
|
||||
//go:build !go1.18
|
||||
// +build !go1.18
|
||||
|
||||
package idna
|
||||
|
||||
const transitionalLookup = true
|
|
@ -49,6 +49,7 @@ func decode(encoded string) (string, error) {
|
|||
}
|
||||
}
|
||||
i, n, bias := int32(0), initialN, initialBias
|
||||
overflow := false
|
||||
for pos < len(encoded) {
|
||||
oldI, w := i, int32(1)
|
||||
for k := base; ; k += base {
|
||||
|
@ -60,29 +61,32 @@ func decode(encoded string) (string, error) {
|
|||
return "", punyError(encoded)
|
||||
}
|
||||
pos++
|
||||
i += digit * w
|
||||
if i < 0 {
|
||||
i, overflow = madd(i, digit, w)
|
||||
if overflow {
|
||||
return "", punyError(encoded)
|
||||
}
|
||||
t := k - bias
|
||||
if t < tmin {
|
||||
if k <= bias {
|
||||
t = tmin
|
||||
} else if t > tmax {
|
||||
} else if k >= bias+tmax {
|
||||
t = tmax
|
||||
}
|
||||
if digit < t {
|
||||
break
|
||||
}
|
||||
w *= base - t
|
||||
if w >= math.MaxInt32/base {
|
||||
w, overflow = madd(0, w, base-t)
|
||||
if overflow {
|
||||
return "", punyError(encoded)
|
||||
}
|
||||
}
|
||||
if len(output) >= 1024 {
|
||||
return "", punyError(encoded)
|
||||
}
|
||||
x := int32(len(output) + 1)
|
||||
bias = adapt(i-oldI, x, oldI == 0)
|
||||
n += i / x
|
||||
i %= x
|
||||
if n > utf8.MaxRune || len(output) >= 1024 {
|
||||
if n < 0 || n > utf8.MaxRune {
|
||||
return "", punyError(encoded)
|
||||
}
|
||||
output = append(output, 0)
|
||||
|
@ -115,6 +119,7 @@ func encode(prefix, s string) (string, error) {
|
|||
if b > 0 {
|
||||
output = append(output, '-')
|
||||
}
|
||||
overflow := false
|
||||
for remaining != 0 {
|
||||
m := int32(0x7fffffff)
|
||||
for _, r := range s {
|
||||
|
@ -122,8 +127,8 @@ func encode(prefix, s string) (string, error) {
|
|||
m = r
|
||||
}
|
||||
}
|
||||
delta += (m - n) * (h + 1)
|
||||
if delta < 0 {
|
||||
delta, overflow = madd(delta, m-n, h+1)
|
||||
if overflow {
|
||||
return "", punyError(s)
|
||||
}
|
||||
n = m
|
||||
|
@ -141,9 +146,9 @@ func encode(prefix, s string) (string, error) {
|
|||
q := delta
|
||||
for k := base; ; k += base {
|
||||
t := k - bias
|
||||
if t < tmin {
|
||||
if k <= bias {
|
||||
t = tmin
|
||||
} else if t > tmax {
|
||||
} else if k >= bias+tmax {
|
||||
t = tmax
|
||||
}
|
||||
if q < t {
|
||||
|
@ -164,6 +169,15 @@ func encode(prefix, s string) (string, error) {
|
|||
return string(output), nil
|
||||
}
|
||||
|
||||
// madd computes a + (b * c), detecting overflow.
|
||||
func madd(a, b, c int32) (next int32, overflow bool) {
|
||||
p := int64(b) * int64(c)
|
||||
if p > math.MaxInt32-int64(a) {
|
||||
return 0, true
|
||||
}
|
||||
return a + int32(p), false
|
||||
}
|
||||
|
||||
func decodeDigit(x byte) (digit int32, ok bool) {
|
||||
switch {
|
||||
case '0' <= x && x <= '9':
|
||||
|
|
|
@ -90,9 +90,10 @@ func archInit() {
|
|||
osSupportsAVX = isSet(1, eax) && isSet(2, eax)
|
||||
|
||||
if runtime.GOOS == "darwin" {
|
||||
// Check darwin commpage for AVX512 support. Necessary because:
|
||||
// https://github.com/apple/darwin-xnu/blob/0a798f6738bc1db01281fc08ae024145e84df927/osfmk/i386/fpu.c#L175-L201
|
||||
osSupportsAVX512 = osSupportsAVX && darwinSupportsAVX512()
|
||||
// Darwin doesn't save/restore AVX-512 mask registers correctly across signal handlers.
|
||||
// Since users can't rely on mask register contents, let's not advertise AVX-512 support.
|
||||
// See issue 49233.
|
||||
osSupportsAVX512 = false
|
||||
} else {
|
||||
// Check if OPMASK and ZMM registers have OS support.
|
||||
osSupportsAVX512 = osSupportsAVX && isSet(5, eax) && isSet(6, eax) && isSet(7, eax)
|
||||
|
|
|
@ -26,27 +26,3 @@ TEXT ·xgetbv(SB),NOSPLIT,$0-8
|
|||
MOVL AX, eax+0(FP)
|
||||
MOVL DX, edx+4(FP)
|
||||
RET
|
||||
|
||||
// func darwinSupportsAVX512() bool
|
||||
TEXT ·darwinSupportsAVX512(SB), NOSPLIT, $0-1
|
||||
MOVB $0, ret+0(FP) // default to false
|
||||
#ifdef GOOS_darwin // return if not darwin
|
||||
#ifdef GOARCH_amd64 // return if not amd64
|
||||
// These values from:
|
||||
// https://github.com/apple/darwin-xnu/blob/xnu-4570.1.46/osfmk/i386/cpu_capabilities.h
|
||||
#define commpage64_base_address 0x00007fffffe00000
|
||||
#define commpage64_cpu_capabilities64 (commpage64_base_address+0x010)
|
||||
#define commpage64_version (commpage64_base_address+0x01E)
|
||||
#define hasAVX512F 0x0000004000000000
|
||||
MOVQ $commpage64_version, BX
|
||||
CMPW (BX), $13 // cpu_capabilities64 undefined in versions < 13
|
||||
JL no_avx512
|
||||
MOVQ $commpage64_cpu_capabilities64, BX
|
||||
MOVQ $hasAVX512F, CX
|
||||
TESTQ (BX), CX
|
||||
JZ no_avx512
|
||||
MOVB $1, ret+0(FP)
|
||||
no_avx512:
|
||||
#endif
|
||||
#endif
|
||||
RET
|
||||
|
|
|
@ -34,3 +34,56 @@ func ParseUnixCredentials(m *SocketControlMessage) (*Ucred, error) {
|
|||
ucred := *(*Ucred)(unsafe.Pointer(&m.Data[0]))
|
||||
return &ucred, nil
|
||||
}
|
||||
|
||||
// PktInfo4 encodes Inet4Pktinfo into a socket control message of type IP_PKTINFO.
|
||||
func PktInfo4(info *Inet4Pktinfo) []byte {
|
||||
b := make([]byte, CmsgSpace(SizeofInet4Pktinfo))
|
||||
h := (*Cmsghdr)(unsafe.Pointer(&b[0]))
|
||||
h.Level = SOL_IP
|
||||
h.Type = IP_PKTINFO
|
||||
h.SetLen(CmsgLen(SizeofInet4Pktinfo))
|
||||
*(*Inet4Pktinfo)(h.data(0)) = *info
|
||||
return b
|
||||
}
|
||||
|
||||
// PktInfo6 encodes Inet6Pktinfo into a socket control message of type IPV6_PKTINFO.
|
||||
func PktInfo6(info *Inet6Pktinfo) []byte {
|
||||
b := make([]byte, CmsgSpace(SizeofInet6Pktinfo))
|
||||
h := (*Cmsghdr)(unsafe.Pointer(&b[0]))
|
||||
h.Level = SOL_IPV6
|
||||
h.Type = IPV6_PKTINFO
|
||||
h.SetLen(CmsgLen(SizeofInet6Pktinfo))
|
||||
*(*Inet6Pktinfo)(h.data(0)) = *info
|
||||
return b
|
||||
}
|
||||
|
||||
// ParseOrigDstAddr decodes a socket control message containing the original
|
||||
// destination address. To receive such a message the IP_RECVORIGDSTADDR or
|
||||
// IPV6_RECVORIGDSTADDR option must be enabled on the socket.
|
||||
func ParseOrigDstAddr(m *SocketControlMessage) (Sockaddr, error) {
|
||||
switch {
|
||||
case m.Header.Level == SOL_IP && m.Header.Type == IP_ORIGDSTADDR:
|
||||
pp := (*RawSockaddrInet4)(unsafe.Pointer(&m.Data[0]))
|
||||
sa := new(SockaddrInet4)
|
||||
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
|
||||
sa.Port = int(p[0])<<8 + int(p[1])
|
||||
for i := 0; i < len(sa.Addr); i++ {
|
||||
sa.Addr[i] = pp.Addr[i]
|
||||
}
|
||||
return sa, nil
|
||||
|
||||
case m.Header.Level == SOL_IPV6 && m.Header.Type == IPV6_ORIGDSTADDR:
|
||||
pp := (*RawSockaddrInet6)(unsafe.Pointer(&m.Data[0]))
|
||||
sa := new(SockaddrInet6)
|
||||
p := (*[2]byte)(unsafe.Pointer(&pp.Port))
|
||||
sa.Port = int(p[0])<<8 + int(p[1])
|
||||
sa.ZoneId = pp.Scope_id
|
||||
for i := 0; i < len(sa.Addr); i++ {
|
||||
sa.Addr[i] = pp.Addr[i]
|
||||
}
|
||||
return sa, nil
|
||||
|
||||
default:
|
||||
return nil, EINVAL
|
||||
}
|
||||
}
|
||||
|
|
|
@ -430,8 +430,25 @@ func GetsockoptXucred(fd, level, opt int) (*Xucred, error) {
|
|||
return x, err
|
||||
}
|
||||
|
||||
func SysctlKinfoProcSlice(name string) ([]KinfoProc, error) {
|
||||
mib, err := sysctlmib(name)
|
||||
func SysctlKinfoProc(name string, args ...int) (*KinfoProc, error) {
|
||||
mib, err := sysctlmib(name, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var kinfo KinfoProc
|
||||
n := uintptr(SizeofKinfoProc)
|
||||
if err := sysctl(mib, (*byte)(unsafe.Pointer(&kinfo)), &n, nil, 0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if n != SizeofKinfoProc {
|
||||
return nil, EIO
|
||||
}
|
||||
return &kinfo, nil
|
||||
}
|
||||
|
||||
func SysctlKinfoProcSlice(name string, args ...int) ([]KinfoProc, error) {
|
||||
mib, err := sysctlmib(name, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -116,6 +116,7 @@ const (
|
|||
ARPHRD_LAPB = 0x204
|
||||
ARPHRD_LOCALTLK = 0x305
|
||||
ARPHRD_LOOPBACK = 0x304
|
||||
ARPHRD_MCTP = 0x122
|
||||
ARPHRD_METRICOM = 0x17
|
||||
ARPHRD_NETLINK = 0x338
|
||||
ARPHRD_NETROM = 0x0
|
||||
|
@ -472,6 +473,7 @@ const (
|
|||
DM_DEV_WAIT = 0xc138fd08
|
||||
DM_DIR = "mapper"
|
||||
DM_GET_TARGET_VERSION = 0xc138fd11
|
||||
DM_IMA_MEASUREMENT_FLAG = 0x80000
|
||||
DM_INACTIVE_PRESENT_FLAG = 0x40
|
||||
DM_INTERNAL_SUSPEND_FLAG = 0x40000
|
||||
DM_IOCTL = 0xfd
|
||||
|
@ -716,6 +718,7 @@ const (
|
|||
ETH_P_LOOPBACK = 0x9000
|
||||
ETH_P_MACSEC = 0x88e5
|
||||
ETH_P_MAP = 0xf9
|
||||
ETH_P_MCTP = 0xfa
|
||||
ETH_P_MOBITEX = 0x15
|
||||
ETH_P_MPLS_MC = 0x8848
|
||||
ETH_P_MPLS_UC = 0x8847
|
||||
|
@ -751,6 +754,21 @@ const (
|
|||
ETH_P_WCCP = 0x883e
|
||||
ETH_P_X25 = 0x805
|
||||
ETH_P_XDSA = 0xf8
|
||||
EV_ABS = 0x3
|
||||
EV_CNT = 0x20
|
||||
EV_FF = 0x15
|
||||
EV_FF_STATUS = 0x17
|
||||
EV_KEY = 0x1
|
||||
EV_LED = 0x11
|
||||
EV_MAX = 0x1f
|
||||
EV_MSC = 0x4
|
||||
EV_PWR = 0x16
|
||||
EV_REL = 0x2
|
||||
EV_REP = 0x14
|
||||
EV_SND = 0x12
|
||||
EV_SW = 0x5
|
||||
EV_SYN = 0x0
|
||||
EV_VERSION = 0x10001
|
||||
EXABYTE_ENABLE_NEST = 0xf0
|
||||
EXT2_SUPER_MAGIC = 0xef53
|
||||
EXT3_SUPER_MAGIC = 0xef53
|
||||
|
@ -789,9 +807,11 @@ const (
|
|||
FAN_DELETE_SELF = 0x400
|
||||
FAN_DENY = 0x2
|
||||
FAN_ENABLE_AUDIT = 0x40
|
||||
FAN_EPIDFD = -0x2
|
||||
FAN_EVENT_INFO_TYPE_DFID = 0x3
|
||||
FAN_EVENT_INFO_TYPE_DFID_NAME = 0x2
|
||||
FAN_EVENT_INFO_TYPE_FID = 0x1
|
||||
FAN_EVENT_INFO_TYPE_PIDFD = 0x4
|
||||
FAN_EVENT_METADATA_LEN = 0x18
|
||||
FAN_EVENT_ON_CHILD = 0x8000000
|
||||
FAN_MARK_ADD = 0x1
|
||||
|
@ -811,6 +831,7 @@ const (
|
|||
FAN_MOVE_SELF = 0x800
|
||||
FAN_NOFD = -0x1
|
||||
FAN_NONBLOCK = 0x2
|
||||
FAN_NOPIDFD = -0x1
|
||||
FAN_ONDIR = 0x40000000
|
||||
FAN_OPEN = 0x20
|
||||
FAN_OPEN_EXEC = 0x1000
|
||||
|
@ -821,6 +842,7 @@ const (
|
|||
FAN_REPORT_DIR_FID = 0x400
|
||||
FAN_REPORT_FID = 0x200
|
||||
FAN_REPORT_NAME = 0x800
|
||||
FAN_REPORT_PIDFD = 0x80
|
||||
FAN_REPORT_TID = 0x100
|
||||
FAN_UNLIMITED_MARKS = 0x20
|
||||
FAN_UNLIMITED_QUEUE = 0x10
|
||||
|
@ -1997,6 +2019,7 @@ const (
|
|||
PR_SPEC_ENABLE = 0x2
|
||||
PR_SPEC_FORCE_DISABLE = 0x8
|
||||
PR_SPEC_INDIRECT_BRANCH = 0x1
|
||||
PR_SPEC_L1D_FLUSH = 0x2
|
||||
PR_SPEC_NOT_AFFECTED = 0x0
|
||||
PR_SPEC_PRCTL = 0x1
|
||||
PR_SPEC_STORE_BYPASS = 0x0
|
||||
|
@ -2432,12 +2455,15 @@ const (
|
|||
SMART_WRITE_THRESHOLDS = 0xd7
|
||||
SMB_SUPER_MAGIC = 0x517b
|
||||
SOCKFS_MAGIC = 0x534f434b
|
||||
SOCK_BUF_LOCK_MASK = 0x3
|
||||
SOCK_DCCP = 0x6
|
||||
SOCK_IOC_TYPE = 0x89
|
||||
SOCK_PACKET = 0xa
|
||||
SOCK_RAW = 0x3
|
||||
SOCK_RCVBUF_LOCK = 0x2
|
||||
SOCK_RDM = 0x4
|
||||
SOCK_SEQPACKET = 0x5
|
||||
SOCK_SNDBUF_LOCK = 0x1
|
||||
SOL_AAL = 0x109
|
||||
SOL_ALG = 0x117
|
||||
SOL_ATM = 0x108
|
||||
|
|
|
@ -293,6 +293,7 @@ const (
|
|||
SO_BPF_EXTENSIONS = 0x30
|
||||
SO_BROADCAST = 0x6
|
||||
SO_BSDCOMPAT = 0xe
|
||||
SO_BUF_LOCK = 0x48
|
||||
SO_BUSY_POLL = 0x2e
|
||||
SO_BUSY_POLL_BUDGET = 0x46
|
||||
SO_CNX_ADVICE = 0x35
|
||||
|
|
|
@ -294,6 +294,7 @@ const (
|
|||
SO_BPF_EXTENSIONS = 0x30
|
||||
SO_BROADCAST = 0x6
|
||||
SO_BSDCOMPAT = 0xe
|
||||
SO_BUF_LOCK = 0x48
|
||||
SO_BUSY_POLL = 0x2e
|
||||
SO_BUSY_POLL_BUDGET = 0x46
|
||||
SO_CNX_ADVICE = 0x35
|
||||
|
|
|
@ -300,6 +300,7 @@ const (
|
|||
SO_BPF_EXTENSIONS = 0x30
|
||||
SO_BROADCAST = 0x6
|
||||
SO_BSDCOMPAT = 0xe
|
||||
SO_BUF_LOCK = 0x48
|
||||
SO_BUSY_POLL = 0x2e
|
||||
SO_BUSY_POLL_BUDGET = 0x46
|
||||
SO_CNX_ADVICE = 0x35
|
||||
|
|
|
@ -290,6 +290,7 @@ const (
|
|||
SO_BPF_EXTENSIONS = 0x30
|
||||
SO_BROADCAST = 0x6
|
||||
SO_BSDCOMPAT = 0xe
|
||||
SO_BUF_LOCK = 0x48
|
||||
SO_BUSY_POLL = 0x2e
|
||||
SO_BUSY_POLL_BUDGET = 0x46
|
||||
SO_CNX_ADVICE = 0x35
|
||||
|
|
|
@ -293,6 +293,7 @@ const (
|
|||
SO_BPF_EXTENSIONS = 0x30
|
||||
SO_BROADCAST = 0x20
|
||||
SO_BSDCOMPAT = 0xe
|
||||
SO_BUF_LOCK = 0x48
|
||||
SO_BUSY_POLL = 0x2e
|
||||
SO_BUSY_POLL_BUDGET = 0x46
|
||||
SO_CNX_ADVICE = 0x35
|
||||
|
|
|
@ -293,6 +293,7 @@ const (
|
|||
SO_BPF_EXTENSIONS = 0x30
|
||||
SO_BROADCAST = 0x20
|
||||
SO_BSDCOMPAT = 0xe
|
||||
SO_BUF_LOCK = 0x48
|
||||
SO_BUSY_POLL = 0x2e
|
||||
SO_BUSY_POLL_BUDGET = 0x46
|
||||
SO_CNX_ADVICE = 0x35
|
||||
|
|
|
@ -293,6 +293,7 @@ const (
|
|||
SO_BPF_EXTENSIONS = 0x30
|
||||
SO_BROADCAST = 0x20
|
||||
SO_BSDCOMPAT = 0xe
|
||||
SO_BUF_LOCK = 0x48
|
||||
SO_BUSY_POLL = 0x2e
|
||||
SO_BUSY_POLL_BUDGET = 0x46
|
||||
SO_CNX_ADVICE = 0x35
|
||||
|
|
|
@ -293,6 +293,7 @@ const (
|
|||
SO_BPF_EXTENSIONS = 0x30
|
||||
SO_BROADCAST = 0x20
|
||||
SO_BSDCOMPAT = 0xe
|
||||
SO_BUF_LOCK = 0x48
|
||||
SO_BUSY_POLL = 0x2e
|
||||
SO_BUSY_POLL_BUDGET = 0x46
|
||||
SO_CNX_ADVICE = 0x35
|
||||
|
|
|
@ -348,6 +348,7 @@ const (
|
|||
SO_BPF_EXTENSIONS = 0x30
|
||||
SO_BROADCAST = 0x6
|
||||
SO_BSDCOMPAT = 0xe
|
||||
SO_BUF_LOCK = 0x48
|
||||
SO_BUSY_POLL = 0x2e
|
||||
SO_BUSY_POLL_BUDGET = 0x46
|
||||
SO_CNX_ADVICE = 0x35
|
||||
|
|
|
@ -352,6 +352,7 @@ const (
|
|||
SO_BPF_EXTENSIONS = 0x30
|
||||
SO_BROADCAST = 0x6
|
||||
SO_BSDCOMPAT = 0xe
|
||||
SO_BUF_LOCK = 0x48
|
||||
SO_BUSY_POLL = 0x2e
|
||||
SO_BUSY_POLL_BUDGET = 0x46
|
||||
SO_CNX_ADVICE = 0x35
|
||||
|
|
|
@ -352,6 +352,7 @@ const (
|
|||
SO_BPF_EXTENSIONS = 0x30
|
||||
SO_BROADCAST = 0x6
|
||||
SO_BSDCOMPAT = 0xe
|
||||
SO_BUF_LOCK = 0x48
|
||||
SO_BUSY_POLL = 0x2e
|
||||
SO_BUSY_POLL_BUDGET = 0x46
|
||||
SO_CNX_ADVICE = 0x35
|
||||
|
|
|
@ -281,6 +281,7 @@ const (
|
|||
SO_BPF_EXTENSIONS = 0x30
|
||||
SO_BROADCAST = 0x6
|
||||
SO_BSDCOMPAT = 0xe
|
||||
SO_BUF_LOCK = 0x48
|
||||
SO_BUSY_POLL = 0x2e
|
||||
SO_BUSY_POLL_BUDGET = 0x46
|
||||
SO_CNX_ADVICE = 0x35
|
||||
|
|
|
@ -356,6 +356,7 @@ const (
|
|||
SO_BPF_EXTENSIONS = 0x30
|
||||
SO_BROADCAST = 0x6
|
||||
SO_BSDCOMPAT = 0xe
|
||||
SO_BUF_LOCK = 0x48
|
||||
SO_BUSY_POLL = 0x2e
|
||||
SO_BUSY_POLL_BUDGET = 0x46
|
||||
SO_CNX_ADVICE = 0x35
|
||||
|
|
|
@ -347,6 +347,7 @@ const (
|
|||
SO_BPF_EXTENSIONS = 0x32
|
||||
SO_BROADCAST = 0x20
|
||||
SO_BSDCOMPAT = 0x400
|
||||
SO_BUF_LOCK = 0x51
|
||||
SO_BUSY_POLL = 0x30
|
||||
SO_BUSY_POLL_BUDGET = 0x49
|
||||
SO_CNX_ADVICE = 0x37
|
||||
|
|
|
@ -444,4 +444,5 @@ const (
|
|||
SYS_LANDLOCK_ADD_RULE = 445
|
||||
SYS_LANDLOCK_RESTRICT_SELF = 446
|
||||
SYS_MEMFD_SECRET = 447
|
||||
SYS_PROCESS_MRELEASE = 448
|
||||
)
|
||||
|
|
|
@ -366,4 +366,5 @@ const (
|
|||
SYS_LANDLOCK_ADD_RULE = 445
|
||||
SYS_LANDLOCK_RESTRICT_SELF = 446
|
||||
SYS_MEMFD_SECRET = 447
|
||||
SYS_PROCESS_MRELEASE = 448
|
||||
)
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
package unix
|
||||
|
||||
const (
|
||||
SYS_SYSCALL_MASK = 0
|
||||
SYS_RESTART_SYSCALL = 0
|
||||
SYS_EXIT = 1
|
||||
SYS_FORK = 2
|
||||
|
@ -407,4 +408,5 @@ const (
|
|||
SYS_LANDLOCK_CREATE_RULESET = 444
|
||||
SYS_LANDLOCK_ADD_RULE = 445
|
||||
SYS_LANDLOCK_RESTRICT_SELF = 446
|
||||
SYS_PROCESS_MRELEASE = 448
|
||||
)
|
||||
|
|
|
@ -311,4 +311,5 @@ const (
|
|||
SYS_LANDLOCK_ADD_RULE = 445
|
||||
SYS_LANDLOCK_RESTRICT_SELF = 446
|
||||
SYS_MEMFD_SECRET = 447
|
||||
SYS_PROCESS_MRELEASE = 448
|
||||
)
|
||||
|
|
|
@ -428,4 +428,5 @@ const (
|
|||
SYS_LANDLOCK_CREATE_RULESET = 4444
|
||||
SYS_LANDLOCK_ADD_RULE = 4445
|
||||
SYS_LANDLOCK_RESTRICT_SELF = 4446
|
||||
SYS_PROCESS_MRELEASE = 4448
|
||||
)
|
||||
|
|
|
@ -358,4 +358,5 @@ const (
|
|||
SYS_LANDLOCK_CREATE_RULESET = 5444
|
||||
SYS_LANDLOCK_ADD_RULE = 5445
|
||||
SYS_LANDLOCK_RESTRICT_SELF = 5446
|
||||
SYS_PROCESS_MRELEASE = 5448
|
||||
)
|
||||
|
|
|
@ -358,4 +358,5 @@ const (
|
|||
SYS_LANDLOCK_CREATE_RULESET = 5444
|
||||
SYS_LANDLOCK_ADD_RULE = 5445
|
||||
SYS_LANDLOCK_RESTRICT_SELF = 5446
|
||||
SYS_PROCESS_MRELEASE = 5448
|
||||
)
|
||||
|
|
|
@ -428,4 +428,5 @@ const (
|
|||
SYS_LANDLOCK_CREATE_RULESET = 4444
|
||||
SYS_LANDLOCK_ADD_RULE = 4445
|
||||
SYS_LANDLOCK_RESTRICT_SELF = 4446
|
||||
SYS_PROCESS_MRELEASE = 4448
|
||||
)
|
||||
|
|
|
@ -435,4 +435,5 @@ const (
|
|||
SYS_LANDLOCK_CREATE_RULESET = 444
|
||||
SYS_LANDLOCK_ADD_RULE = 445
|
||||
SYS_LANDLOCK_RESTRICT_SELF = 446
|
||||
SYS_PROCESS_MRELEASE = 448
|
||||
)
|
||||
|
|
|
@ -407,4 +407,5 @@ const (
|
|||
SYS_LANDLOCK_CREATE_RULESET = 444
|
||||
SYS_LANDLOCK_ADD_RULE = 445
|
||||
SYS_LANDLOCK_RESTRICT_SELF = 446
|
||||
SYS_PROCESS_MRELEASE = 448
|
||||
)
|
||||
|
|
|
@ -407,4 +407,5 @@ const (
|
|||
SYS_LANDLOCK_CREATE_RULESET = 444
|
||||
SYS_LANDLOCK_ADD_RULE = 445
|
||||
SYS_LANDLOCK_RESTRICT_SELF = 446
|
||||
SYS_PROCESS_MRELEASE = 448
|
||||
)
|
||||
|
|
|
@ -309,4 +309,5 @@ const (
|
|||
SYS_LANDLOCK_CREATE_RULESET = 444
|
||||
SYS_LANDLOCK_ADD_RULE = 445
|
||||
SYS_LANDLOCK_RESTRICT_SELF = 446
|
||||
SYS_PROCESS_MRELEASE = 448
|
||||
)
|
||||
|
|
|
@ -372,4 +372,5 @@ const (
|
|||
SYS_LANDLOCK_CREATE_RULESET = 444
|
||||
SYS_LANDLOCK_ADD_RULE = 445
|
||||
SYS_LANDLOCK_RESTRICT_SELF = 446
|
||||
SYS_PROCESS_MRELEASE = 448
|
||||
)
|
||||
|
|
|
@ -386,4 +386,5 @@ const (
|
|||
SYS_LANDLOCK_CREATE_RULESET = 444
|
||||
SYS_LANDLOCK_ADD_RULE = 445
|
||||
SYS_LANDLOCK_RESTRICT_SELF = 446
|
||||
SYS_PROCESS_MRELEASE = 448
|
||||
)
|
||||
|
|
|
@ -641,13 +641,13 @@ type Eproc struct {
|
|||
Tdev int32
|
||||
Tpgid int32
|
||||
Tsess uintptr
|
||||
Wmesg [8]int8
|
||||
Wmesg [8]byte
|
||||
Xsize int32
|
||||
Xrssize int16
|
||||
Xccount int16
|
||||
Xswrss int16
|
||||
Flag int32
|
||||
Login [12]int8
|
||||
Login [12]byte
|
||||
Spare [4]int32
|
||||
_ [4]byte
|
||||
}
|
||||
|
@ -688,7 +688,7 @@ type ExternProc struct {
|
|||
P_priority uint8
|
||||
P_usrpri uint8
|
||||
P_nice int8
|
||||
P_comm [17]int8
|
||||
P_comm [17]byte
|
||||
P_pgrp uintptr
|
||||
P_addr uintptr
|
||||
P_xstat uint16
|
||||
|
|
|
@ -641,13 +641,13 @@ type Eproc struct {
|
|||
Tdev int32
|
||||
Tpgid int32
|
||||
Tsess uintptr
|
||||
Wmesg [8]int8
|
||||
Wmesg [8]byte
|
||||
Xsize int32
|
||||
Xrssize int16
|
||||
Xccount int16
|
||||
Xswrss int16
|
||||
Flag int32
|
||||
Login [12]int8
|
||||
Login [12]byte
|
||||
Spare [4]int32
|
||||
_ [4]byte
|
||||
}
|
||||
|
@ -688,7 +688,7 @@ type ExternProc struct {
|
|||
P_priority uint8
|
||||
P_usrpri uint8
|
||||
P_nice int8
|
||||
P_comm [17]int8
|
||||
P_comm [17]byte
|
||||
P_pgrp uintptr
|
||||
P_addr uintptr
|
||||
P_xstat uint16
|
||||
|
|
|
@ -3264,7 +3264,8 @@ const (
|
|||
LWTUNNEL_ENCAP_BPF = 0x6
|
||||
LWTUNNEL_ENCAP_SEG6_LOCAL = 0x7
|
||||
LWTUNNEL_ENCAP_RPL = 0x8
|
||||
LWTUNNEL_ENCAP_MAX = 0x8
|
||||
LWTUNNEL_ENCAP_IOAM6 = 0x9
|
||||
LWTUNNEL_ENCAP_MAX = 0x9
|
||||
|
||||
MPLS_IPTUNNEL_UNSPEC = 0x0
|
||||
MPLS_IPTUNNEL_DST = 0x1
|
||||
|
@ -3617,7 +3618,9 @@ const (
|
|||
ETHTOOL_A_COALESCE_TX_USECS_HIGH = 0x15
|
||||
ETHTOOL_A_COALESCE_TX_MAX_FRAMES_HIGH = 0x16
|
||||
ETHTOOL_A_COALESCE_RATE_SAMPLE_INTERVAL = 0x17
|
||||
ETHTOOL_A_COALESCE_MAX = 0x17
|
||||
ETHTOOL_A_COALESCE_USE_CQE_MODE_TX = 0x18
|
||||
ETHTOOL_A_COALESCE_USE_CQE_MODE_RX = 0x19
|
||||
ETHTOOL_A_COALESCE_MAX = 0x19
|
||||
ETHTOOL_A_PAUSE_UNSPEC = 0x0
|
||||
ETHTOOL_A_PAUSE_HEADER = 0x1
|
||||
ETHTOOL_A_PAUSE_AUTONEG = 0x2
|
||||
|
|
|
@ -564,12 +564,11 @@ type Uvmexp struct {
|
|||
Kmapent int32
|
||||
}
|
||||
|
||||
const SizeofClockinfo = 0x14
|
||||
const SizeofClockinfo = 0x10
|
||||
|
||||
type Clockinfo struct {
|
||||
Hz int32
|
||||
Tick int32
|
||||
Tickadj int32
|
||||
Stathz int32
|
||||
Profhz int32
|
||||
Hz int32
|
||||
Tick int32
|
||||
Stathz int32
|
||||
Profhz int32
|
||||
}
|
||||
|
|
|
@ -564,12 +564,11 @@ type Uvmexp struct {
|
|||
Kmapent int32
|
||||
}
|
||||
|
||||
const SizeofClockinfo = 0x14
|
||||
const SizeofClockinfo = 0x10
|
||||
|
||||
type Clockinfo struct {
|
||||
Hz int32
|
||||
Tick int32
|
||||
Tickadj int32
|
||||
Stathz int32
|
||||
Profhz int32
|
||||
Hz int32
|
||||
Tick int32
|
||||
Stathz int32
|
||||
Profhz int32
|
||||
}
|
||||
|
|
|
@ -565,12 +565,11 @@ type Uvmexp struct {
|
|||
Kmapent int32
|
||||
}
|
||||
|
||||
const SizeofClockinfo = 0x14
|
||||
const SizeofClockinfo = 0x10
|
||||
|
||||
type Clockinfo struct {
|
||||
Hz int32
|
||||
Tick int32
|
||||
Tickadj int32
|
||||
Stathz int32
|
||||
Profhz int32
|
||||
Hz int32
|
||||
Tick int32
|
||||
Stathz int32
|
||||
Profhz int32
|
||||
}
|
||||
|
|
|
@ -558,12 +558,11 @@ type Uvmexp struct {
|
|||
Kmapent int32
|
||||
}
|
||||
|
||||
const SizeofClockinfo = 0x14
|
||||
const SizeofClockinfo = 0x10
|
||||
|
||||
type Clockinfo struct {
|
||||
Hz int32
|
||||
Tick int32
|
||||
Tickadj int32
|
||||
Stathz int32
|
||||
Profhz int32
|
||||
Hz int32
|
||||
Tick int32
|
||||
Stathz int32
|
||||
Profhz int32
|
||||
}
|
||||
|
|
|
@ -558,12 +558,11 @@ type Uvmexp struct {
|
|||
Kmapent int32
|
||||
}
|
||||
|
||||
const SizeofClockinfo = 0x14
|
||||
const SizeofClockinfo = 0x10
|
||||
|
||||
type Clockinfo struct {
|
||||
Hz int32
|
||||
Tick int32
|
||||
Tickadj int32
|
||||
Stathz int32
|
||||
Profhz int32
|
||||
Hz int32
|
||||
Tick int32
|
||||
Stathz int32
|
||||
Profhz int32
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build windows
|
||||
// +build go1.9
|
||||
//go:build windows && go1.9
|
||||
// +build windows,go1.9
|
||||
|
||||
package windows
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package windows
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build generate
|
||||
// +build generate
|
||||
|
||||
package windows
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build windows && race
|
||||
// +build windows,race
|
||||
|
||||
package windows
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build windows && !race
|
||||
// +build windows,!race
|
||||
|
||||
package windows
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package windows
|
||||
|
@ -16,8 +17,6 @@ const (
|
|||
SC_MANAGER_ALL_ACCESS = 0xf003f
|
||||
)
|
||||
|
||||
//sys OpenSCManager(machineName *uint16, databaseName *uint16, access uint32) (handle Handle, err error) [failretval==0] = advapi32.OpenSCManagerW
|
||||
|
||||
const (
|
||||
SERVICE_KERNEL_DRIVER = 1
|
||||
SERVICE_FILE_SYSTEM_DRIVER = 2
|
||||
|
@ -132,6 +131,14 @@ const (
|
|||
SC_EVENT_DATABASE_CHANGE = 0
|
||||
SC_EVENT_PROPERTY_CHANGE = 1
|
||||
SC_EVENT_STATUS_CHANGE = 2
|
||||
|
||||
SERVICE_START_REASON_DEMAND = 0x00000001
|
||||
SERVICE_START_REASON_AUTO = 0x00000002
|
||||
SERVICE_START_REASON_TRIGGER = 0x00000004
|
||||
SERVICE_START_REASON_RESTART_ON_FAILURE = 0x00000008
|
||||
SERVICE_START_REASON_DELAYEDAUTO = 0x00000010
|
||||
|
||||
SERVICE_DYNAMIC_INFORMATION_LEVEL_START_REASON = 1
|
||||
)
|
||||
|
||||
type SERVICE_STATUS struct {
|
||||
|
@ -216,6 +223,7 @@ type QUERY_SERVICE_LOCK_STATUS struct {
|
|||
LockDuration uint32
|
||||
}
|
||||
|
||||
//sys OpenSCManager(machineName *uint16, databaseName *uint16, access uint32) (handle Handle, err error) [failretval==0] = advapi32.OpenSCManagerW
|
||||
//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
|
||||
|
@ -235,3 +243,5 @@ type QUERY_SERVICE_LOCK_STATUS struct {
|
|||
//sys NotifyServiceStatusChange(service Handle, notifyMask uint32, notifier *SERVICE_NOTIFY) (ret error) = advapi32.NotifyServiceStatusChangeW
|
||||
//sys SubscribeServiceChangeNotifications(service Handle, eventType uint32, callback uintptr, callbackCtx uintptr, subscription *uintptr) (ret error) = sechost.SubscribeServiceChangeNotifications?
|
||||
//sys UnsubscribeServiceChangeNotifications(subscription uintptr) = sechost.UnsubscribeServiceChangeNotifications?
|
||||
//sys RegisterServiceCtrlHandlerEx(serviceName *uint16, handlerProc uintptr, context uintptr) (handle Handle, err error) = advapi32.RegisterServiceCtrlHandlerExW
|
||||
//sys QueryServiceDynamicInformation(service Handle, infoLevel uint32, dynamicInfo unsafe.Pointer) (err error) = advapi32.QueryServiceDynamicInformation?
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package windows
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build windows
|
||||
|
||||
package svc
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
// event represents auto-reset, initially non-signaled Windows event.
|
||||
// It is used to communicate between go and asm parts of this package.
|
||||
type event struct {
|
||||
h windows.Handle
|
||||
}
|
||||
|
||||
func newEvent() (*event, error) {
|
||||
h, err := windows.CreateEvent(nil, 0, 0, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &event{h: h}, nil
|
||||
}
|
||||
|
||||
func (e *event) Close() error {
|
||||
return windows.CloseHandle(e.h)
|
||||
}
|
||||
|
||||
func (e *event) Set() error {
|
||||
return windows.SetEvent(e.h)
|
||||
}
|
||||
|
||||
func (e *event) Wait() error {
|
||||
s, err := windows.WaitForSingleObject(e.h, windows.INFINITE)
|
||||
switch s {
|
||||
case windows.WAIT_OBJECT_0:
|
||||
break
|
||||
case windows.WAIT_FAILED:
|
||||
return err
|
||||
default:
|
||||
return errors.New("unexpected result from WaitForSingleObject")
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build windows
|
||||
// +build !go1.3
|
||||
|
||||
// copied from pkg/runtime
|
||||
typedef unsigned int uint32;
|
||||
typedef unsigned long long int uint64;
|
||||
#ifdef _64BIT
|
||||
typedef uint64 uintptr;
|
||||
#else
|
||||
typedef uint32 uintptr;
|
||||
#endif
|
||||
|
||||
// from sys_386.s or sys_amd64.s
|
||||
void ·servicemain(void);
|
||||
|
||||
void
|
||||
·getServiceMain(uintptr *r)
|
||||
{
|
||||
*r = (uintptr)·servicemain;
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build windows
|
||||
// +build !go1.3
|
||||
|
||||
package svc
|
||||
|
||||
// from go12.c
|
||||
func getServiceMain(r *uintptr)
|
|
@ -1,31 +0,0 @@
|
|||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build windows
|
||||
// +build go1.3
|
||||
|
||||
package svc
|
||||
|
||||
import "unsafe"
|
||||
|
||||
const ptrSize = 4 << (^uintptr(0) >> 63) // unsafe.Sizeof(uintptr(0)) but an ideal const
|
||||
|
||||
// Should be a built-in for unsafe.Pointer?
|
||||
func add(p unsafe.Pointer, x uintptr) unsafe.Pointer {
|
||||
return unsafe.Pointer(uintptr(p) + x)
|
||||
}
|
||||
|
||||
// funcPC returns the entry PC of the function f.
|
||||
// It assumes that f is a func value. Otherwise the behavior is undefined.
|
||||
func funcPC(f interface{}) uintptr {
|
||||
return **(**uintptr)(add(unsafe.Pointer(&f), ptrSize))
|
||||
}
|
||||
|
||||
// from sys_386.s and sys_amd64.s
|
||||
func servicectlhandler(ctl uint32) uintptr
|
||||
func servicemain(argc uint32, argv **uint16)
|
||||
|
||||
func getServiceMain(r *uintptr) {
|
||||
*r = funcPC(servicemain)
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package svc
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
// Package svc provides everything required to build Windows service.
|
||||
|
@ -10,8 +11,7 @@ package svc
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"runtime"
|
||||
"syscall"
|
||||
"sync"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/internal/unsafeheader"
|
||||
|
@ -80,6 +80,17 @@ type Status struct {
|
|||
ServiceSpecificExitCode uint32 // set if the service has exited with a service-specific exit code
|
||||
}
|
||||
|
||||
// StartReason is the reason that the service was started.
|
||||
type StartReason uint32
|
||||
|
||||
const (
|
||||
StartReasonDemand = StartReason(windows.SERVICE_START_REASON_DEMAND)
|
||||
StartReasonAuto = StartReason(windows.SERVICE_START_REASON_AUTO)
|
||||
StartReasonTrigger = StartReason(windows.SERVICE_START_REASON_TRIGGER)
|
||||
StartReasonRestartOnFailure = StartReason(windows.SERVICE_START_REASON_RESTART_ON_FAILURE)
|
||||
StartReasonDelayedAuto = StartReason(windows.SERVICE_START_REASON_DELAYEDAUTO)
|
||||
)
|
||||
|
||||
// ChangeRequest is sent to the service Handler to request service status change.
|
||||
type ChangeRequest struct {
|
||||
Cmd Cmd
|
||||
|
@ -91,7 +102,6 @@ type ChangeRequest struct {
|
|||
|
||||
// Handler is the interface that must be implemented to build Windows service.
|
||||
type Handler interface {
|
||||
|
||||
// Execute will be called by the package code at the start of
|
||||
// the service, and the service will exit once Execute completes.
|
||||
// Inside Execute you must read service change requests from r and
|
||||
|
@ -106,28 +116,6 @@ type Handler interface {
|
|||
Execute(args []string, r <-chan ChangeRequest, s chan<- Status) (svcSpecificEC bool, exitCode uint32)
|
||||
}
|
||||
|
||||
var (
|
||||
// These are used by asm code.
|
||||
goWaitsH uintptr
|
||||
cWaitsH uintptr
|
||||
ssHandle uintptr
|
||||
sName *uint16
|
||||
sArgc uintptr
|
||||
sArgv **uint16
|
||||
ctlHandlerExProc uintptr
|
||||
cSetEvent uintptr
|
||||
cWaitForSingleObject uintptr
|
||||
cRegisterServiceCtrlHandlerExW uintptr
|
||||
)
|
||||
|
||||
func init() {
|
||||
k := windows.NewLazySystemDLL("kernel32.dll")
|
||||
cSetEvent = k.NewProc("SetEvent").Addr()
|
||||
cWaitForSingleObject = k.NewProc("WaitForSingleObject").Addr()
|
||||
a := windows.NewLazySystemDLL("advapi32.dll")
|
||||
cRegisterServiceCtrlHandlerExW = a.NewProc("RegisterServiceCtrlHandlerExW").Addr()
|
||||
}
|
||||
|
||||
type ctlEvent struct {
|
||||
cmd Cmd
|
||||
eventType uint32
|
||||
|
@ -140,36 +128,10 @@ type ctlEvent struct {
|
|||
type service struct {
|
||||
name string
|
||||
h windows.Handle
|
||||
cWaits *event
|
||||
goWaits *event
|
||||
c chan ctlEvent
|
||||
handler Handler
|
||||
}
|
||||
|
||||
func newService(name string, handler Handler) (*service, error) {
|
||||
var s service
|
||||
var err error
|
||||
s.name = name
|
||||
s.c = make(chan ctlEvent)
|
||||
s.handler = handler
|
||||
s.cWaits, err = newEvent()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s.goWaits, err = newEvent()
|
||||
if err != nil {
|
||||
s.cWaits.Close()
|
||||
return nil, err
|
||||
}
|
||||
return &s, nil
|
||||
}
|
||||
|
||||
func (s *service) close() error {
|
||||
s.cWaits.Close()
|
||||
s.goWaits.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
type exitCode struct {
|
||||
isSvcSpecific bool
|
||||
errno uint32
|
||||
|
@ -224,23 +186,42 @@ func (s *service) updateStatus(status *Status, ec *exitCode) error {
|
|||
return windows.SetServiceStatus(s.h, &t)
|
||||
}
|
||||
|
||||
const (
|
||||
sysErrSetServiceStatusFailed = uint32(syscall.APPLICATION_ERROR) + iota
|
||||
sysErrNewThreadInCallback
|
||||
var (
|
||||
initCallbacks sync.Once
|
||||
ctlHandlerCallback uintptr
|
||||
serviceMainCallback uintptr
|
||||
)
|
||||
|
||||
func (s *service) run() {
|
||||
s.goWaits.Wait()
|
||||
s.h = windows.Handle(ssHandle)
|
||||
func ctlHandler(ctl, evtype, evdata, context uintptr) uintptr {
|
||||
s := (*service)(unsafe.Pointer(context))
|
||||
e := ctlEvent{cmd: Cmd(ctl), eventType: uint32(evtype), eventData: evdata, context: 123456} // Set context to 123456 to test issue #25660.
|
||||
s.c <- e
|
||||
return 0
|
||||
}
|
||||
|
||||
var argv []*uint16
|
||||
hdr := (*unsafeheader.Slice)(unsafe.Pointer(&argv))
|
||||
hdr.Data = unsafe.Pointer(sArgv)
|
||||
hdr.Len = int(sArgc)
|
||||
hdr.Cap = int(sArgc)
|
||||
var theService service // This is, unfortunately, a global, which means only one service per process.
|
||||
|
||||
args := make([]string, len(argv))
|
||||
for i, a := range argv {
|
||||
// serviceMain is the entry point called by the service manager, registered earlier by
|
||||
// the call to StartServiceCtrlDispatcher.
|
||||
func serviceMain(argc uint32, argv **uint16) uintptr {
|
||||
handle, err := windows.RegisterServiceCtrlHandlerEx(windows.StringToUTF16Ptr(theService.name), ctlHandlerCallback, uintptr(unsafe.Pointer(&theService)))
|
||||
if sysErr, ok := err.(windows.Errno); ok {
|
||||
return uintptr(sysErr)
|
||||
} else if err != nil {
|
||||
return uintptr(windows.ERROR_UNKNOWN_EXCEPTION)
|
||||
}
|
||||
theService.h = handle
|
||||
defer func() {
|
||||
theService.h = 0
|
||||
}()
|
||||
var args16 []*uint16
|
||||
hdr := (*unsafeheader.Slice)(unsafe.Pointer(&args16))
|
||||
hdr.Data = unsafe.Pointer(argv)
|
||||
hdr.Len = int(argc)
|
||||
hdr.Cap = int(argc)
|
||||
|
||||
args := make([]string, len(args16))
|
||||
for i, a := range args16 {
|
||||
args[i] = windows.UTF16PtrToString(a)
|
||||
}
|
||||
|
||||
|
@ -249,7 +230,7 @@ func (s *service) run() {
|
|||
exitFromHandler := make(chan exitCode)
|
||||
|
||||
go func() {
|
||||
ss, errno := s.handler.Execute(args, cmdsToHandler, changesFromHandler)
|
||||
ss, errno := theService.handler.Execute(args, cmdsToHandler, changesFromHandler)
|
||||
exitFromHandler <- exitCode{ss, errno}
|
||||
}()
|
||||
|
||||
|
@ -258,7 +239,7 @@ func (s *service) run() {
|
|||
CurrentStatus: Status{State: Stopped},
|
||||
}
|
||||
var outch chan ChangeRequest
|
||||
inch := s.c
|
||||
inch := theService.c
|
||||
loop:
|
||||
for {
|
||||
select {
|
||||
|
@ -274,14 +255,13 @@ loop:
|
|||
outcr.EventData = r.eventData
|
||||
outcr.Context = r.context
|
||||
case outch <- outcr:
|
||||
inch = s.c
|
||||
inch = theService.c
|
||||
outch = nil
|
||||
case c := <-changesFromHandler:
|
||||
err := s.updateStatus(&c, &ec)
|
||||
err := theService.updateStatus(&c, &ec)
|
||||
if err != nil {
|
||||
// best suitable error number
|
||||
ec.errno = sysErrSetServiceStatusFailed
|
||||
if err2, ok := err.(syscall.Errno); ok {
|
||||
ec.errno = uint32(windows.ERROR_EXCEPTION_IN_SERVICE)
|
||||
if err2, ok := err.(windows.Errno); ok {
|
||||
ec.errno = uint32(err2)
|
||||
}
|
||||
break loop
|
||||
|
@ -292,87 +272,43 @@ loop:
|
|||
}
|
||||
}
|
||||
|
||||
s.updateStatus(&Status{State: Stopped}, &ec)
|
||||
s.cWaits.Set()
|
||||
}
|
||||
theService.updateStatus(&Status{State: Stopped}, &ec)
|
||||
|
||||
func newCallback(fn interface{}) (cb uintptr, err error) {
|
||||
defer func() {
|
||||
r := recover()
|
||||
if r == nil {
|
||||
return
|
||||
}
|
||||
cb = 0
|
||||
switch v := r.(type) {
|
||||
case string:
|
||||
err = errors.New(v)
|
||||
case error:
|
||||
err = v
|
||||
default:
|
||||
err = errors.New("unexpected panic in syscall.NewCallback")
|
||||
}
|
||||
}()
|
||||
return syscall.NewCallback(fn), nil
|
||||
return windows.NO_ERROR
|
||||
}
|
||||
|
||||
// BUG(brainman): There is no mechanism to run multiple services
|
||||
// inside one single executable. Perhaps, it can be overcome by
|
||||
// using RegisterServiceCtrlHandlerEx Windows api.
|
||||
|
||||
// Run executes service name by calling appropriate handler function.
|
||||
func Run(name string, handler Handler) error {
|
||||
runtime.LockOSThread()
|
||||
|
||||
tid := windows.GetCurrentThreadId()
|
||||
|
||||
s, err := newService(name, handler)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ctlHandler := func(ctl, evtype, evdata, context uintptr) uintptr {
|
||||
e := ctlEvent{cmd: Cmd(ctl), eventType: uint32(evtype), eventData: evdata, context: context}
|
||||
// We assume that this callback function is running on
|
||||
// the same thread as Run. Nowhere in MS documentation
|
||||
// I could find statement to guarantee that. So putting
|
||||
// check here to verify, otherwise things will go bad
|
||||
// quickly, if ignored.
|
||||
i := windows.GetCurrentThreadId()
|
||||
if i != tid {
|
||||
e.errno = sysErrNewThreadInCallback
|
||||
}
|
||||
s.c <- e
|
||||
// Always return NO_ERROR (0) for now.
|
||||
return windows.NO_ERROR
|
||||
}
|
||||
|
||||
var svcmain uintptr
|
||||
getServiceMain(&svcmain)
|
||||
initCallbacks.Do(func() {
|
||||
ctlHandlerCallback = windows.NewCallback(ctlHandler)
|
||||
serviceMainCallback = windows.NewCallback(serviceMain)
|
||||
})
|
||||
theService.name = name
|
||||
theService.handler = handler
|
||||
theService.c = make(chan ctlEvent)
|
||||
t := []windows.SERVICE_TABLE_ENTRY{
|
||||
{ServiceName: syscall.StringToUTF16Ptr(s.name), ServiceProc: svcmain},
|
||||
{ServiceName: windows.StringToUTF16Ptr(theService.name), ServiceProc: serviceMainCallback},
|
||||
{ServiceName: nil, ServiceProc: 0},
|
||||
}
|
||||
|
||||
goWaitsH = uintptr(s.goWaits.h)
|
||||
cWaitsH = uintptr(s.cWaits.h)
|
||||
sName = t[0].ServiceName
|
||||
ctlHandlerExProc, err = newCallback(ctlHandler)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
go s.run()
|
||||
|
||||
err = windows.StartServiceCtrlDispatcher(&t[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return windows.StartServiceCtrlDispatcher(&t[0])
|
||||
}
|
||||
|
||||
// StatusHandle returns service status handle. It is safe to call this function
|
||||
// from inside the Handler.Execute because then it is guaranteed to be set.
|
||||
// This code will have to change once multiple services are possible per process.
|
||||
func StatusHandle() windows.Handle {
|
||||
return windows.Handle(ssHandle)
|
||||
return theService.h
|
||||
}
|
||||
|
||||
// DynamicStartReason returns the reason why the service was started. It is safe
|
||||
// to call this function from inside the Handler.Execute because then it is
|
||||
// guaranteed to be set.
|
||||
func DynamicStartReason() (StartReason, error) {
|
||||
var allocReason *uint32
|
||||
err := windows.QueryServiceDynamicInformation(theService.h, windows.SERVICE_DYNAMIC_INFORMATION_LEVEL_START_REASON, unsafe.Pointer(&allocReason))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
reason := StartReason(*allocReason)
|
||||
windows.LocalFree(windows.Handle(unsafe.Pointer(allocReason)))
|
||||
return reason, nil
|
||||
}
|
||||
|
|
|
@ -1,67 +0,0 @@
|
|||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// func servicemain(argc uint32, argv **uint16)
|
||||
TEXT ·servicemain(SB),7,$0
|
||||
MOVL argc+0(FP), AX
|
||||
MOVL AX, ·sArgc(SB)
|
||||
MOVL argv+4(FP), AX
|
||||
MOVL AX, ·sArgv(SB)
|
||||
|
||||
PUSHL BP
|
||||
PUSHL BX
|
||||
PUSHL SI
|
||||
PUSHL DI
|
||||
|
||||
SUBL $12, SP
|
||||
|
||||
MOVL ·sName(SB), AX
|
||||
MOVL AX, (SP)
|
||||
MOVL $·servicectlhandler(SB), AX
|
||||
MOVL AX, 4(SP)
|
||||
// Set context to 123456 to test issue #25660.
|
||||
MOVL $123456, 8(SP)
|
||||
MOVL ·cRegisterServiceCtrlHandlerExW(SB), AX
|
||||
MOVL SP, BP
|
||||
CALL AX
|
||||
MOVL BP, SP
|
||||
CMPL AX, $0
|
||||
JE exit
|
||||
MOVL AX, ·ssHandle(SB)
|
||||
|
||||
MOVL ·goWaitsH(SB), AX
|
||||
MOVL AX, (SP)
|
||||
MOVL ·cSetEvent(SB), AX
|
||||
MOVL SP, BP
|
||||
CALL AX
|
||||
MOVL BP, SP
|
||||
|
||||
MOVL ·cWaitsH(SB), AX
|
||||
MOVL AX, (SP)
|
||||
MOVL $-1, AX
|
||||
MOVL AX, 4(SP)
|
||||
MOVL ·cWaitForSingleObject(SB), AX
|
||||
MOVL SP, BP
|
||||
CALL AX
|
||||
MOVL BP, SP
|
||||
|
||||
exit:
|
||||
ADDL $12, SP
|
||||
|
||||
POPL DI
|
||||
POPL SI
|
||||
POPL BX
|
||||
POPL BP
|
||||
|
||||
MOVL 0(SP), CX
|
||||
ADDL $12, SP
|
||||
JMP CX
|
||||
|
||||
// I do not know why, but this seems to be the only way to call
|
||||
// ctlHandlerProc on Windows 7.
|
||||
|
||||
// func servicectlhandler(ctl uint32, evtype uint32, evdata uintptr, context uintptr) uintptr {
|
||||
TEXT ·servicectlhandler(SB),7,$0
|
||||
MOVL ·ctlHandlerExProc(SB), CX
|
||||
JMP CX
|
|
@ -1,46 +0,0 @@
|
|||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// func servicemain(argc uint32, argv **uint16)
|
||||
TEXT ·servicemain(SB),7,$0
|
||||
MOVQ SP, AX
|
||||
ANDQ $~15, SP // alignment as per Windows requirement
|
||||
SUBQ $48, SP // room for SP and 4 args as per Windows requirement
|
||||
// plus one extra word to keep stack 16 bytes aligned
|
||||
MOVQ AX, 32(SP)
|
||||
|
||||
MOVL CX, ·sArgc(SB)
|
||||
MOVQ DX, ·sArgv(SB)
|
||||
|
||||
MOVQ ·sName(SB), CX
|
||||
MOVQ $·servicectlhandler(SB), DX
|
||||
// BUG(pastarmovj): Figure out a way to pass in context in R8.
|
||||
// Set context to 123456 to test issue #25660.
|
||||
MOVQ $123456, R8
|
||||
MOVQ ·cRegisterServiceCtrlHandlerExW(SB), AX
|
||||
CALL AX
|
||||
CMPQ AX, $0
|
||||
JE exit
|
||||
MOVQ AX, ·ssHandle(SB)
|
||||
|
||||
MOVQ ·goWaitsH(SB), CX
|
||||
MOVQ ·cSetEvent(SB), AX
|
||||
CALL AX
|
||||
|
||||
MOVQ ·cWaitsH(SB), CX
|
||||
MOVQ $4294967295, DX
|
||||
MOVQ ·cWaitForSingleObject(SB), AX
|
||||
CALL AX
|
||||
|
||||
exit:
|
||||
MOVQ 32(SP), SP
|
||||
RET
|
||||
|
||||
// I do not know why, but this seems to be the only way to call
|
||||
// ctlHandlerProc on Windows 7.
|
||||
|
||||
// func ·servicectlhandler(ctl uint32, evtype uint32, evdata uintptr, context uintptr) uintptr {
|
||||
TEXT ·servicectlhandler(SB),7,$0
|
||||
MOVQ ·ctlHandlerExProc(SB), AX
|
||||
JMP AX
|
|
@ -1,36 +0,0 @@
|
|||
// 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.
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// func servicemain(argc uint32, argv **uint16)
|
||||
TEXT ·servicemain(SB),NOSPLIT|NOFRAME,$0
|
||||
MOVM.DB.W [R4, R14], (R13) // push {r4, lr}
|
||||
MOVW R13, R4
|
||||
BIC $0x7, R13 // alignment for ABI
|
||||
|
||||
MOVW R0, ·sArgc(SB)
|
||||
MOVW R1, ·sArgv(SB)
|
||||
|
||||
MOVW ·sName(SB), R0
|
||||
MOVW ·ctlHandlerExProc(SB), R1
|
||||
MOVW $0, R2
|
||||
MOVW ·cRegisterServiceCtrlHandlerExW(SB), R3
|
||||
BL (R3)
|
||||
CMP $0, R0
|
||||
BEQ exit
|
||||
MOVW R0, ·ssHandle(SB)
|
||||
|
||||
MOVW ·goWaitsH(SB), R0
|
||||
MOVW ·cSetEvent(SB), R1
|
||||
BL (R1)
|
||||
|
||||
MOVW ·cWaitsH(SB), R0
|
||||
MOVW $-1, R1
|
||||
MOVW ·cWaitForSingleObject(SB), R2
|
||||
BL (R2)
|
||||
|
||||
exit:
|
||||
MOVW R4, R13 // free extra stack space
|
||||
MOVM.IA.W (R13), [R4, R15] // pop {r4, pc}
|
|
@ -1,31 +0,0 @@
|
|||
// 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.
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// func servicemain(argc uint32, argv **uint16)
|
||||
TEXT ·servicemain(SB),NOSPLIT|NOFRAME,$0
|
||||
MOVD R0, ·sArgc(SB)
|
||||
MOVD R1, ·sArgv(SB)
|
||||
|
||||
MOVD ·sName(SB), R0
|
||||
MOVD ·ctlHandlerExProc(SB), R1
|
||||
MOVD $0, R2
|
||||
MOVD ·cRegisterServiceCtrlHandlerExW(SB), R3
|
||||
BL (R3)
|
||||
CMP $0, R0
|
||||
BEQ exit
|
||||
MOVD R0, ·ssHandle(SB)
|
||||
|
||||
MOVD ·goWaitsH(SB), R0
|
||||
MOVD ·cSetEvent(SB), R1
|
||||
BL (R1)
|
||||
|
||||
MOVD ·cWaitsH(SB), R0
|
||||
MOVD $-1, R1
|
||||
MOVD ·cWaitForSingleObject(SB), R2
|
||||
BL (R2)
|
||||
|
||||
exit:
|
||||
RET
|
|
@ -2,6 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
// Package windows contains an interface to the low-level operating system
|
||||
|
|
|
@ -401,6 +401,11 @@ func NewCallbackCDecl(fn interface{}) uintptr {
|
|||
//sys LoadResource(module Handle, resInfo Handle) (resData Handle, err error) = kernel32.LoadResource
|
||||
//sys LockResource(resData Handle) (addr uintptr, err error) = kernel32.LockResource
|
||||
|
||||
// Version APIs
|
||||
//sys GetFileVersionInfoSize(filename string, zeroHandle *Handle) (bufSize uint32, err error) = version.GetFileVersionInfoSizeW
|
||||
//sys GetFileVersionInfo(filename string, handle uint32, bufSize uint32, buffer unsafe.Pointer) (err error) = version.GetFileVersionInfoW
|
||||
//sys VerQueryValue(block unsafe.Pointer, subBlock string, pointerToBufferPointer unsafe.Pointer, bufSize *uint32) (err error) = version.VerQueryValueW
|
||||
|
||||
// Process Status API (PSAPI)
|
||||
//sys EnumProcesses(processIds []uint32, bytesReturned *uint32) (err error) = psapi.EnumProcesses
|
||||
//sys EnumProcessModules(process Handle, module *Handle, cb uint32, cbNeeded *uint32) (err error) = psapi.EnumProcessModules
|
||||
|
@ -418,11 +423,16 @@ func NewCallbackCDecl(fn interface{}) uintptr {
|
|||
//sys RtlInitString(destinationString *NTString, sourceString *byte) = ntdll.RtlInitString
|
||||
//sys NtCreateFile(handle *Handle, access uint32, oa *OBJECT_ATTRIBUTES, iosb *IO_STATUS_BLOCK, allocationSize *int64, attributes uint32, share uint32, disposition uint32, options uint32, eabuffer uintptr, ealength uint32) (ntstatus error) = ntdll.NtCreateFile
|
||||
//sys NtCreateNamedPipeFile(pipe *Handle, access uint32, oa *OBJECT_ATTRIBUTES, iosb *IO_STATUS_BLOCK, share uint32, disposition uint32, options uint32, typ uint32, readMode uint32, completionMode uint32, maxInstances uint32, inboundQuota uint32, outputQuota uint32, timeout *int64) (ntstatus error) = ntdll.NtCreateNamedPipeFile
|
||||
//sys NtSetInformationFile(handle Handle, iosb *IO_STATUS_BLOCK, inBuffer *byte, inBufferLen uint32, class uint32) (ntstatus error) = ntdll.NtSetInformationFile
|
||||
//sys RtlDosPathNameToNtPathName(dosName *uint16, ntName *NTUnicodeString, ntFileNamePart *uint16, relativeName *RTL_RELATIVE_NAME) (ntstatus error) = ntdll.RtlDosPathNameToNtPathName_U_WithStatus
|
||||
//sys RtlDosPathNameToRelativeNtPathName(dosName *uint16, ntName *NTUnicodeString, ntFileNamePart *uint16, relativeName *RTL_RELATIVE_NAME) (ntstatus error) = ntdll.RtlDosPathNameToRelativeNtPathName_U_WithStatus
|
||||
//sys RtlDefaultNpAcl(acl **ACL) (ntstatus error) = ntdll.RtlDefaultNpAcl
|
||||
//sys NtQueryInformationProcess(proc Handle, procInfoClass int32, procInfo unsafe.Pointer, procInfoLen uint32, retLen *uint32) (ntstatus error) = ntdll.NtQueryInformationProcess
|
||||
//sys NtSetInformationProcess(proc Handle, procInfoClass int32, procInfo unsafe.Pointer, procInfoLen uint32) (ntstatus error) = ntdll.NtSetInformationProcess
|
||||
//sys NtQuerySystemInformation(sysInfoClass int32, sysInfo unsafe.Pointer, sysInfoLen uint32, retLen *uint32) (ntstatus error) = ntdll.NtQuerySystemInformation
|
||||
//sys NtSetSystemInformation(sysInfoClass int32, sysInfo unsafe.Pointer, sysInfoLen uint32) (ntstatus error) = ntdll.NtSetSystemInformation
|
||||
//sys RtlAddFunctionTable(functionTable *RUNTIME_FUNCTION, entryCount uint32, baseAddress uintptr) (ret bool) = ntdll.RtlAddFunctionTable
|
||||
//sys RtlDeleteFunctionTable(functionTable *RUNTIME_FUNCTION) (ret bool) = ntdll.RtlDeleteFunctionTable
|
||||
|
||||
// syscall interface implementation for other packages
|
||||
|
||||
|
|
|
@ -66,9 +66,21 @@ var signals = [...]string{
|
|||
}
|
||||
|
||||
const (
|
||||
FILE_LIST_DIRECTORY = 0x00000001
|
||||
FILE_APPEND_DATA = 0x00000004
|
||||
FILE_READ_DATA = 0x00000001
|
||||
FILE_READ_ATTRIBUTES = 0x00000080
|
||||
FILE_READ_EA = 0x00000008
|
||||
FILE_WRITE_DATA = 0x00000002
|
||||
FILE_WRITE_ATTRIBUTES = 0x00000100
|
||||
FILE_WRITE_EA = 0x00000010
|
||||
FILE_APPEND_DATA = 0x00000004
|
||||
FILE_EXECUTE = 0x00000020
|
||||
|
||||
FILE_GENERIC_READ = STANDARD_RIGHTS_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE
|
||||
FILE_GENERIC_WRITE = STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA | SYNCHRONIZE
|
||||
FILE_GENERIC_EXECUTE = STANDARD_RIGHTS_EXECUTE | FILE_READ_ATTRIBUTES | FILE_EXECUTE | SYNCHRONIZE
|
||||
|
||||
FILE_LIST_DIRECTORY = 0x00000001
|
||||
FILE_TRAVERSE = 0x00000020
|
||||
|
||||
FILE_SHARE_READ = 0x00000001
|
||||
FILE_SHARE_WRITE = 0x00000002
|
||||
|
@ -1789,7 +1801,53 @@ type reparseDataBuffer struct {
|
|||
}
|
||||
|
||||
const (
|
||||
FSCTL_GET_REPARSE_POINT = 0x900A8
|
||||
FSCTL_CREATE_OR_GET_OBJECT_ID = 0x0900C0
|
||||
FSCTL_DELETE_OBJECT_ID = 0x0900A0
|
||||
FSCTL_DELETE_REPARSE_POINT = 0x0900AC
|
||||
FSCTL_DUPLICATE_EXTENTS_TO_FILE = 0x098344
|
||||
FSCTL_DUPLICATE_EXTENTS_TO_FILE_EX = 0x0983E8
|
||||
FSCTL_FILESYSTEM_GET_STATISTICS = 0x090060
|
||||
FSCTL_FILE_LEVEL_TRIM = 0x098208
|
||||
FSCTL_FIND_FILES_BY_SID = 0x09008F
|
||||
FSCTL_GET_COMPRESSION = 0x09003C
|
||||
FSCTL_GET_INTEGRITY_INFORMATION = 0x09027C
|
||||
FSCTL_GET_NTFS_VOLUME_DATA = 0x090064
|
||||
FSCTL_GET_REFS_VOLUME_DATA = 0x0902D8
|
||||
FSCTL_GET_OBJECT_ID = 0x09009C
|
||||
FSCTL_GET_REPARSE_POINT = 0x0900A8
|
||||
FSCTL_GET_RETRIEVAL_POINTER_COUNT = 0x09042B
|
||||
FSCTL_GET_RETRIEVAL_POINTERS = 0x090073
|
||||
FSCTL_GET_RETRIEVAL_POINTERS_AND_REFCOUNT = 0x0903D3
|
||||
FSCTL_IS_PATHNAME_VALID = 0x09002C
|
||||
FSCTL_LMR_SET_LINK_TRACKING_INFORMATION = 0x1400EC
|
||||
FSCTL_MARK_HANDLE = 0x0900FC
|
||||
FSCTL_OFFLOAD_READ = 0x094264
|
||||
FSCTL_OFFLOAD_WRITE = 0x098268
|
||||
FSCTL_PIPE_PEEK = 0x11400C
|
||||
FSCTL_PIPE_TRANSCEIVE = 0x11C017
|
||||
FSCTL_PIPE_WAIT = 0x110018
|
||||
FSCTL_QUERY_ALLOCATED_RANGES = 0x0940CF
|
||||
FSCTL_QUERY_FAT_BPB = 0x090058
|
||||
FSCTL_QUERY_FILE_REGIONS = 0x090284
|
||||
FSCTL_QUERY_ON_DISK_VOLUME_INFO = 0x09013C
|
||||
FSCTL_QUERY_SPARING_INFO = 0x090138
|
||||
FSCTL_READ_FILE_USN_DATA = 0x0900EB
|
||||
FSCTL_RECALL_FILE = 0x090117
|
||||
FSCTL_REFS_STREAM_SNAPSHOT_MANAGEMENT = 0x090440
|
||||
FSCTL_SET_COMPRESSION = 0x09C040
|
||||
FSCTL_SET_DEFECT_MANAGEMENT = 0x098134
|
||||
FSCTL_SET_ENCRYPTION = 0x0900D7
|
||||
FSCTL_SET_INTEGRITY_INFORMATION = 0x09C280
|
||||
FSCTL_SET_INTEGRITY_INFORMATION_EX = 0x090380
|
||||
FSCTL_SET_OBJECT_ID = 0x090098
|
||||
FSCTL_SET_OBJECT_ID_EXTENDED = 0x0900BC
|
||||
FSCTL_SET_REPARSE_POINT = 0x0900A4
|
||||
FSCTL_SET_SPARSE = 0x0900C4
|
||||
FSCTL_SET_ZERO_DATA = 0x0980C8
|
||||
FSCTL_SET_ZERO_ON_DEALLOCATION = 0x090194
|
||||
FSCTL_SIS_COPYFILE = 0x090100
|
||||
FSCTL_WRITE_USN_CLOSE_RECORD = 0x0900EF
|
||||
|
||||
MAXIMUM_REPARSE_DATA_BUFFER_SIZE = 16 * 1024
|
||||
IO_REPARSE_TAG_MOUNT_POINT = 0xA0000003
|
||||
IO_REPARSE_TAG_SYMLINK = 0xA000000C
|
||||
|
@ -2308,6 +2366,12 @@ type LIST_ENTRY struct {
|
|||
Blink *LIST_ENTRY
|
||||
}
|
||||
|
||||
type RUNTIME_FUNCTION struct {
|
||||
BeginAddress uint32
|
||||
EndAddress uint32
|
||||
UnwindData uint32
|
||||
}
|
||||
|
||||
type LDR_DATA_TABLE_ENTRY struct {
|
||||
reserved1 [2]uintptr
|
||||
InMemoryOrderLinks LIST_ENTRY
|
||||
|
@ -2498,6 +2562,60 @@ const (
|
|||
FILE_PIPE_SERVER_END = 0x00000001
|
||||
)
|
||||
|
||||
const (
|
||||
// FileInformationClass for NtSetInformationFile
|
||||
FileBasicInformation = 4
|
||||
FileRenameInformation = 10
|
||||
FileDispositionInformation = 13
|
||||
FilePositionInformation = 14
|
||||
FileEndOfFileInformation = 20
|
||||
FileValidDataLengthInformation = 39
|
||||
FileShortNameInformation = 40
|
||||
FileIoPriorityHintInformation = 43
|
||||
FileReplaceCompletionInformation = 61
|
||||
FileDispositionInformationEx = 64
|
||||
FileCaseSensitiveInformation = 71
|
||||
FileLinkInformation = 72
|
||||
FileCaseSensitiveInformationForceAccessCheck = 75
|
||||
FileKnownFolderInformation = 76
|
||||
|
||||
// Flags for FILE_RENAME_INFORMATION
|
||||
FILE_RENAME_REPLACE_IF_EXISTS = 0x00000001
|
||||
FILE_RENAME_POSIX_SEMANTICS = 0x00000002
|
||||
FILE_RENAME_SUPPRESS_PIN_STATE_INHERITANCE = 0x00000004
|
||||
FILE_RENAME_SUPPRESS_STORAGE_RESERVE_INHERITANCE = 0x00000008
|
||||
FILE_RENAME_NO_INCREASE_AVAILABLE_SPACE = 0x00000010
|
||||
FILE_RENAME_NO_DECREASE_AVAILABLE_SPACE = 0x00000020
|
||||
FILE_RENAME_PRESERVE_AVAILABLE_SPACE = 0x00000030
|
||||
FILE_RENAME_IGNORE_READONLY_ATTRIBUTE = 0x00000040
|
||||
FILE_RENAME_FORCE_RESIZE_TARGET_SR = 0x00000080
|
||||
FILE_RENAME_FORCE_RESIZE_SOURCE_SR = 0x00000100
|
||||
FILE_RENAME_FORCE_RESIZE_SR = 0x00000180
|
||||
|
||||
// Flags for FILE_DISPOSITION_INFORMATION_EX
|
||||
FILE_DISPOSITION_DO_NOT_DELETE = 0x00000000
|
||||
FILE_DISPOSITION_DELETE = 0x00000001
|
||||
FILE_DISPOSITION_POSIX_SEMANTICS = 0x00000002
|
||||
FILE_DISPOSITION_FORCE_IMAGE_SECTION_CHECK = 0x00000004
|
||||
FILE_DISPOSITION_ON_CLOSE = 0x00000008
|
||||
FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE = 0x00000010
|
||||
|
||||
// Flags for FILE_CASE_SENSITIVE_INFORMATION
|
||||
FILE_CS_FLAG_CASE_SENSITIVE_DIR = 0x00000001
|
||||
|
||||
// Flags for FILE_LINK_INFORMATION
|
||||
FILE_LINK_REPLACE_IF_EXISTS = 0x00000001
|
||||
FILE_LINK_POSIX_SEMANTICS = 0x00000002
|
||||
FILE_LINK_SUPPRESS_STORAGE_RESERVE_INHERITANCE = 0x00000008
|
||||
FILE_LINK_NO_INCREASE_AVAILABLE_SPACE = 0x00000010
|
||||
FILE_LINK_NO_DECREASE_AVAILABLE_SPACE = 0x00000020
|
||||
FILE_LINK_PRESERVE_AVAILABLE_SPACE = 0x00000030
|
||||
FILE_LINK_IGNORE_READONLY_ATTRIBUTE = 0x00000040
|
||||
FILE_LINK_FORCE_RESIZE_TARGET_SR = 0x00000080
|
||||
FILE_LINK_FORCE_RESIZE_SOURCE_SR = 0x00000100
|
||||
FILE_LINK_FORCE_RESIZE_SR = 0x00000180
|
||||
)
|
||||
|
||||
// ProcessInformationClasses for NtQueryInformationProcess and NtSetInformationProcess.
|
||||
const (
|
||||
ProcessBasicInformation = iota
|
||||
|
@ -2614,6 +2732,203 @@ type PROCESS_BASIC_INFORMATION struct {
|
|||
InheritedFromUniqueProcessId uintptr
|
||||
}
|
||||
|
||||
// SystemInformationClasses for NtQuerySystemInformation and NtSetSystemInformation
|
||||
const (
|
||||
SystemBasicInformation = iota
|
||||
SystemProcessorInformation
|
||||
SystemPerformanceInformation
|
||||
SystemTimeOfDayInformation
|
||||
SystemPathInformation
|
||||
SystemProcessInformation
|
||||
SystemCallCountInformation
|
||||
SystemDeviceInformation
|
||||
SystemProcessorPerformanceInformation
|
||||
SystemFlagsInformation
|
||||
SystemCallTimeInformation
|
||||
SystemModuleInformation
|
||||
SystemLocksInformation
|
||||
SystemStackTraceInformation
|
||||
SystemPagedPoolInformation
|
||||
SystemNonPagedPoolInformation
|
||||
SystemHandleInformation
|
||||
SystemObjectInformation
|
||||
SystemPageFileInformation
|
||||
SystemVdmInstemulInformation
|
||||
SystemVdmBopInformation
|
||||
SystemFileCacheInformation
|
||||
SystemPoolTagInformation
|
||||
SystemInterruptInformation
|
||||
SystemDpcBehaviorInformation
|
||||
SystemFullMemoryInformation
|
||||
SystemLoadGdiDriverInformation
|
||||
SystemUnloadGdiDriverInformation
|
||||
SystemTimeAdjustmentInformation
|
||||
SystemSummaryMemoryInformation
|
||||
SystemMirrorMemoryInformation
|
||||
SystemPerformanceTraceInformation
|
||||
systemObsolete0
|
||||
SystemExceptionInformation
|
||||
SystemCrashDumpStateInformation
|
||||
SystemKernelDebuggerInformation
|
||||
SystemContextSwitchInformation
|
||||
SystemRegistryQuotaInformation
|
||||
SystemExtendServiceTableInformation
|
||||
SystemPrioritySeperation
|
||||
SystemVerifierAddDriverInformation
|
||||
SystemVerifierRemoveDriverInformation
|
||||
SystemProcessorIdleInformation
|
||||
SystemLegacyDriverInformation
|
||||
SystemCurrentTimeZoneInformation
|
||||
SystemLookasideInformation
|
||||
SystemTimeSlipNotification
|
||||
SystemSessionCreate
|
||||
SystemSessionDetach
|
||||
SystemSessionInformation
|
||||
SystemRangeStartInformation
|
||||
SystemVerifierInformation
|
||||
SystemVerifierThunkExtend
|
||||
SystemSessionProcessInformation
|
||||
SystemLoadGdiDriverInSystemSpace
|
||||
SystemNumaProcessorMap
|
||||
SystemPrefetcherInformation
|
||||
SystemExtendedProcessInformation
|
||||
SystemRecommendedSharedDataAlignment
|
||||
SystemComPlusPackage
|
||||
SystemNumaAvailableMemory
|
||||
SystemProcessorPowerInformation
|
||||
SystemEmulationBasicInformation
|
||||
SystemEmulationProcessorInformation
|
||||
SystemExtendedHandleInformation
|
||||
SystemLostDelayedWriteInformation
|
||||
SystemBigPoolInformation
|
||||
SystemSessionPoolTagInformation
|
||||
SystemSessionMappedViewInformation
|
||||
SystemHotpatchInformation
|
||||
SystemObjectSecurityMode
|
||||
SystemWatchdogTimerHandler
|
||||
SystemWatchdogTimerInformation
|
||||
SystemLogicalProcessorInformation
|
||||
SystemWow64SharedInformationObsolete
|
||||
SystemRegisterFirmwareTableInformationHandler
|
||||
SystemFirmwareTableInformation
|
||||
SystemModuleInformationEx
|
||||
SystemVerifierTriageInformation
|
||||
SystemSuperfetchInformation
|
||||
SystemMemoryListInformation
|
||||
SystemFileCacheInformationEx
|
||||
SystemThreadPriorityClientIdInformation
|
||||
SystemProcessorIdleCycleTimeInformation
|
||||
SystemVerifierCancellationInformation
|
||||
SystemProcessorPowerInformationEx
|
||||
SystemRefTraceInformation
|
||||
SystemSpecialPoolInformation
|
||||
SystemProcessIdInformation
|
||||
SystemErrorPortInformation
|
||||
SystemBootEnvironmentInformation
|
||||
SystemHypervisorInformation
|
||||
SystemVerifierInformationEx
|
||||
SystemTimeZoneInformation
|
||||
SystemImageFileExecutionOptionsInformation
|
||||
SystemCoverageInformation
|
||||
SystemPrefetchPatchInformation
|
||||
SystemVerifierFaultsInformation
|
||||
SystemSystemPartitionInformation
|
||||
SystemSystemDiskInformation
|
||||
SystemProcessorPerformanceDistribution
|
||||
SystemNumaProximityNodeInformation
|
||||
SystemDynamicTimeZoneInformation
|
||||
SystemCodeIntegrityInformation
|
||||
SystemProcessorMicrocodeUpdateInformation
|
||||
SystemProcessorBrandString
|
||||
SystemVirtualAddressInformation
|
||||
SystemLogicalProcessorAndGroupInformation
|
||||
SystemProcessorCycleTimeInformation
|
||||
SystemStoreInformation
|
||||
SystemRegistryAppendString
|
||||
SystemAitSamplingValue
|
||||
SystemVhdBootInformation
|
||||
SystemCpuQuotaInformation
|
||||
SystemNativeBasicInformation
|
||||
systemSpare1
|
||||
SystemLowPriorityIoInformation
|
||||
SystemTpmBootEntropyInformation
|
||||
SystemVerifierCountersInformation
|
||||
SystemPagedPoolInformationEx
|
||||
SystemSystemPtesInformationEx
|
||||
SystemNodeDistanceInformation
|
||||
SystemAcpiAuditInformation
|
||||
SystemBasicPerformanceInformation
|
||||
SystemQueryPerformanceCounterInformation
|
||||
SystemSessionBigPoolInformation
|
||||
SystemBootGraphicsInformation
|
||||
SystemScrubPhysicalMemoryInformation
|
||||
SystemBadPageInformation
|
||||
SystemProcessorProfileControlArea
|
||||
SystemCombinePhysicalMemoryInformation
|
||||
SystemEntropyInterruptTimingCallback
|
||||
SystemConsoleInformation
|
||||
SystemPlatformBinaryInformation
|
||||
SystemThrottleNotificationInformation
|
||||
SystemHypervisorProcessorCountInformation
|
||||
SystemDeviceDataInformation
|
||||
SystemDeviceDataEnumerationInformation
|
||||
SystemMemoryTopologyInformation
|
||||
SystemMemoryChannelInformation
|
||||
SystemBootLogoInformation
|
||||
SystemProcessorPerformanceInformationEx
|
||||
systemSpare0
|
||||
SystemSecureBootPolicyInformation
|
||||
SystemPageFileInformationEx
|
||||
SystemSecureBootInformation
|
||||
SystemEntropyInterruptTimingRawInformation
|
||||
SystemPortableWorkspaceEfiLauncherInformation
|
||||
SystemFullProcessInformation
|
||||
SystemKernelDebuggerInformationEx
|
||||
SystemBootMetadataInformation
|
||||
SystemSoftRebootInformation
|
||||
SystemElamCertificateInformation
|
||||
SystemOfflineDumpConfigInformation
|
||||
SystemProcessorFeaturesInformation
|
||||
SystemRegistryReconciliationInformation
|
||||
SystemEdidInformation
|
||||
SystemManufacturingInformation
|
||||
SystemEnergyEstimationConfigInformation
|
||||
SystemHypervisorDetailInformation
|
||||
SystemProcessorCycleStatsInformation
|
||||
SystemVmGenerationCountInformation
|
||||
SystemTrustedPlatformModuleInformation
|
||||
SystemKernelDebuggerFlags
|
||||
SystemCodeIntegrityPolicyInformation
|
||||
SystemIsolatedUserModeInformation
|
||||
SystemHardwareSecurityTestInterfaceResultsInformation
|
||||
SystemSingleModuleInformation
|
||||
SystemAllowedCpuSetsInformation
|
||||
SystemDmaProtectionInformation
|
||||
SystemInterruptCpuSetsInformation
|
||||
SystemSecureBootPolicyFullInformation
|
||||
SystemCodeIntegrityPolicyFullInformation
|
||||
SystemAffinitizedInterruptProcessorInformation
|
||||
SystemRootSiloInformation
|
||||
)
|
||||
|
||||
type RTL_PROCESS_MODULE_INFORMATION struct {
|
||||
Section Handle
|
||||
MappedBase uintptr
|
||||
ImageBase uintptr
|
||||
ImageSize uint32
|
||||
Flags uint32
|
||||
LoadOrderIndex uint16
|
||||
InitOrderIndex uint16
|
||||
LoadCount uint16
|
||||
OffsetToFileName uint16
|
||||
FullPathName [256]byte
|
||||
}
|
||||
|
||||
type RTL_PROCESS_MODULES struct {
|
||||
NumberOfModules uint32
|
||||
Modules [1]RTL_PROCESS_MODULE_INFORMATION
|
||||
}
|
||||
|
||||
// Constants for LocalAlloc flags.
|
||||
const (
|
||||
LMEM_FIXED = 0x0
|
||||
|
@ -2708,6 +3023,22 @@ var (
|
|||
RT_MANIFEST ResourceID = 24
|
||||
)
|
||||
|
||||
type VS_FIXEDFILEINFO struct {
|
||||
Signature uint32
|
||||
StrucVersion uint32
|
||||
FileVersionMS uint32
|
||||
FileVersionLS uint32
|
||||
ProductVersionMS uint32
|
||||
ProductVersionLS uint32
|
||||
FileFlagsMask uint32
|
||||
FileFlags uint32
|
||||
FileOS uint32
|
||||
FileType uint32
|
||||
FileSubtype uint32
|
||||
FileDateMS uint32
|
||||
FileDateLS uint32
|
||||
}
|
||||
|
||||
type COAUTHIDENTITY struct {
|
||||
User *uint16
|
||||
UserLength uint32
|
||||
|
|
|
@ -51,6 +51,7 @@ var (
|
|||
modshell32 = NewLazySystemDLL("shell32.dll")
|
||||
moduser32 = NewLazySystemDLL("user32.dll")
|
||||
moduserenv = NewLazySystemDLL("userenv.dll")
|
||||
modversion = NewLazySystemDLL("version.dll")
|
||||
modwintrust = NewLazySystemDLL("wintrust.dll")
|
||||
modws2_32 = NewLazySystemDLL("ws2_32.dll")
|
||||
modwtsapi32 = NewLazySystemDLL("wtsapi32.dll")
|
||||
|
@ -114,6 +115,7 @@ var (
|
|||
procOpenThreadToken = modadvapi32.NewProc("OpenThreadToken")
|
||||
procQueryServiceConfig2W = modadvapi32.NewProc("QueryServiceConfig2W")
|
||||
procQueryServiceConfigW = modadvapi32.NewProc("QueryServiceConfigW")
|
||||
procQueryServiceDynamicInformation = modadvapi32.NewProc("QueryServiceDynamicInformation")
|
||||
procQueryServiceLockStatusW = modadvapi32.NewProc("QueryServiceLockStatusW")
|
||||
procQueryServiceStatus = modadvapi32.NewProc("QueryServiceStatus")
|
||||
procQueryServiceStatusEx = modadvapi32.NewProc("QueryServiceStatusEx")
|
||||
|
@ -124,6 +126,7 @@ var (
|
|||
procRegQueryInfoKeyW = modadvapi32.NewProc("RegQueryInfoKeyW")
|
||||
procRegQueryValueExW = modadvapi32.NewProc("RegQueryValueExW")
|
||||
procRegisterEventSourceW = modadvapi32.NewProc("RegisterEventSourceW")
|
||||
procRegisterServiceCtrlHandlerExW = modadvapi32.NewProc("RegisterServiceCtrlHandlerExW")
|
||||
procReportEventW = modadvapi32.NewProc("ReportEventW")
|
||||
procRevertToSelf = modadvapi32.NewProc("RevertToSelf")
|
||||
procSetEntriesInAclW = modadvapi32.NewProc("SetEntriesInAclW")
|
||||
|
@ -365,8 +368,13 @@ var (
|
|||
procNtCreateFile = modntdll.NewProc("NtCreateFile")
|
||||
procNtCreateNamedPipeFile = modntdll.NewProc("NtCreateNamedPipeFile")
|
||||
procNtQueryInformationProcess = modntdll.NewProc("NtQueryInformationProcess")
|
||||
procNtQuerySystemInformation = modntdll.NewProc("NtQuerySystemInformation")
|
||||
procNtSetInformationFile = modntdll.NewProc("NtSetInformationFile")
|
||||
procNtSetInformationProcess = modntdll.NewProc("NtSetInformationProcess")
|
||||
procNtSetSystemInformation = modntdll.NewProc("NtSetSystemInformation")
|
||||
procRtlAddFunctionTable = modntdll.NewProc("RtlAddFunctionTable")
|
||||
procRtlDefaultNpAcl = modntdll.NewProc("RtlDefaultNpAcl")
|
||||
procRtlDeleteFunctionTable = modntdll.NewProc("RtlDeleteFunctionTable")
|
||||
procRtlDosPathNameToNtPathName_U_WithStatus = modntdll.NewProc("RtlDosPathNameToNtPathName_U_WithStatus")
|
||||
procRtlDosPathNameToRelativeNtPathName_U_WithStatus = modntdll.NewProc("RtlDosPathNameToRelativeNtPathName_U_WithStatus")
|
||||
procRtlGetCurrentPeb = modntdll.NewProc("RtlGetCurrentPeb")
|
||||
|
@ -402,6 +410,9 @@ var (
|
|||
procCreateEnvironmentBlock = moduserenv.NewProc("CreateEnvironmentBlock")
|
||||
procDestroyEnvironmentBlock = moduserenv.NewProc("DestroyEnvironmentBlock")
|
||||
procGetUserProfileDirectoryW = moduserenv.NewProc("GetUserProfileDirectoryW")
|
||||
procGetFileVersionInfoSizeW = modversion.NewProc("GetFileVersionInfoSizeW")
|
||||
procGetFileVersionInfoW = modversion.NewProc("GetFileVersionInfoW")
|
||||
procVerQueryValueW = modversion.NewProc("VerQueryValueW")
|
||||
procWinVerifyTrustEx = modwintrust.NewProc("WinVerifyTrustEx")
|
||||
procFreeAddrInfoW = modws2_32.NewProc("FreeAddrInfoW")
|
||||
procGetAddrInfoW = modws2_32.NewProc("GetAddrInfoW")
|
||||
|
@ -966,6 +977,18 @@ func QueryServiceConfig(service Handle, serviceConfig *QUERY_SERVICE_CONFIG, buf
|
|||
return
|
||||
}
|
||||
|
||||
func QueryServiceDynamicInformation(service Handle, infoLevel uint32, dynamicInfo unsafe.Pointer) (err error) {
|
||||
err = procQueryServiceDynamicInformation.Find()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
r1, _, e1 := syscall.Syscall(procQueryServiceDynamicInformation.Addr(), 3, uintptr(service), uintptr(infoLevel), uintptr(dynamicInfo))
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func QueryServiceLockStatus(mgr Handle, lockStatus *QUERY_SERVICE_LOCK_STATUS, bufSize uint32, bytesNeeded *uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procQueryServiceLockStatusW.Addr(), 4, uintptr(mgr), uintptr(unsafe.Pointer(lockStatus)), uintptr(bufSize), uintptr(unsafe.Pointer(bytesNeeded)), 0, 0)
|
||||
if r1 == 0 {
|
||||
|
@ -1055,6 +1078,15 @@ func RegisterEventSource(uncServerName *uint16, sourceName *uint16) (handle Hand
|
|||
return
|
||||
}
|
||||
|
||||
func RegisterServiceCtrlHandlerEx(serviceName *uint16, handlerProc uintptr, context uintptr) (handle Handle, err error) {
|
||||
r0, _, e1 := syscall.Syscall(procRegisterServiceCtrlHandlerExW.Addr(), 3, uintptr(unsafe.Pointer(serviceName)), uintptr(handlerProc), uintptr(context))
|
||||
handle = Handle(r0)
|
||||
if handle == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func ReportEvent(log Handle, etype uint16, category uint16, eventId uint32, usrSId uintptr, numStrings uint16, dataSize uint32, strings **uint16, rawData *byte) (err error) {
|
||||
r1, _, e1 := syscall.Syscall9(procReportEventW.Addr(), 9, uintptr(log), uintptr(etype), uintptr(category), uintptr(eventId), uintptr(usrSId), uintptr(numStrings), uintptr(dataSize), uintptr(unsafe.Pointer(strings)), uintptr(unsafe.Pointer(rawData)))
|
||||
if r1 == 0 {
|
||||
|
@ -3160,6 +3192,22 @@ func NtQueryInformationProcess(proc Handle, procInfoClass int32, procInfo unsafe
|
|||
return
|
||||
}
|
||||
|
||||
func NtQuerySystemInformation(sysInfoClass int32, sysInfo unsafe.Pointer, sysInfoLen uint32, retLen *uint32) (ntstatus error) {
|
||||
r0, _, _ := syscall.Syscall6(procNtQuerySystemInformation.Addr(), 4, uintptr(sysInfoClass), uintptr(sysInfo), uintptr(sysInfoLen), uintptr(unsafe.Pointer(retLen)), 0, 0)
|
||||
if r0 != 0 {
|
||||
ntstatus = NTStatus(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func NtSetInformationFile(handle Handle, iosb *IO_STATUS_BLOCK, inBuffer *byte, inBufferLen uint32, class uint32) (ntstatus error) {
|
||||
r0, _, _ := syscall.Syscall6(procNtSetInformationFile.Addr(), 5, uintptr(handle), uintptr(unsafe.Pointer(iosb)), uintptr(unsafe.Pointer(inBuffer)), uintptr(inBufferLen), uintptr(class), 0)
|
||||
if r0 != 0 {
|
||||
ntstatus = NTStatus(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func NtSetInformationProcess(proc Handle, procInfoClass int32, procInfo unsafe.Pointer, procInfoLen uint32) (ntstatus error) {
|
||||
r0, _, _ := syscall.Syscall6(procNtSetInformationProcess.Addr(), 4, uintptr(proc), uintptr(procInfoClass), uintptr(procInfo), uintptr(procInfoLen), 0, 0)
|
||||
if r0 != 0 {
|
||||
|
@ -3168,6 +3216,20 @@ func NtSetInformationProcess(proc Handle, procInfoClass int32, procInfo unsafe.P
|
|||
return
|
||||
}
|
||||
|
||||
func NtSetSystemInformation(sysInfoClass int32, sysInfo unsafe.Pointer, sysInfoLen uint32) (ntstatus error) {
|
||||
r0, _, _ := syscall.Syscall(procNtSetSystemInformation.Addr(), 3, uintptr(sysInfoClass), uintptr(sysInfo), uintptr(sysInfoLen))
|
||||
if r0 != 0 {
|
||||
ntstatus = NTStatus(r0)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func RtlAddFunctionTable(functionTable *RUNTIME_FUNCTION, entryCount uint32, baseAddress uintptr) (ret bool) {
|
||||
r0, _, _ := syscall.Syscall(procRtlAddFunctionTable.Addr(), 3, uintptr(unsafe.Pointer(functionTable)), uintptr(entryCount), uintptr(baseAddress))
|
||||
ret = r0 != 0
|
||||
return
|
||||
}
|
||||
|
||||
func RtlDefaultNpAcl(acl **ACL) (ntstatus error) {
|
||||
r0, _, _ := syscall.Syscall(procRtlDefaultNpAcl.Addr(), 1, uintptr(unsafe.Pointer(acl)), 0, 0)
|
||||
if r0 != 0 {
|
||||
|
@ -3176,6 +3238,12 @@ func RtlDefaultNpAcl(acl **ACL) (ntstatus error) {
|
|||
return
|
||||
}
|
||||
|
||||
func RtlDeleteFunctionTable(functionTable *RUNTIME_FUNCTION) (ret bool) {
|
||||
r0, _, _ := syscall.Syscall(procRtlDeleteFunctionTable.Addr(), 1, uintptr(unsafe.Pointer(functionTable)), 0, 0)
|
||||
ret = r0 != 0
|
||||
return
|
||||
}
|
||||
|
||||
func RtlDosPathNameToNtPathName(dosName *uint16, ntName *NTUnicodeString, ntFileNamePart *uint16, relativeName *RTL_RELATIVE_NAME) (ntstatus error) {
|
||||
r0, _, _ := syscall.Syscall6(procRtlDosPathNameToNtPathName_U_WithStatus.Addr(), 4, uintptr(unsafe.Pointer(dosName)), uintptr(unsafe.Pointer(ntName)), uintptr(unsafe.Pointer(ntFileNamePart)), uintptr(unsafe.Pointer(relativeName)), 0, 0)
|
||||
if r0 != 0 {
|
||||
|
@ -3449,6 +3517,58 @@ func GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func GetFileVersionInfoSize(filename string, zeroHandle *Handle) (bufSize uint32, err error) {
|
||||
var _p0 *uint16
|
||||
_p0, err = syscall.UTF16PtrFromString(filename)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return _GetFileVersionInfoSize(_p0, zeroHandle)
|
||||
}
|
||||
|
||||
func _GetFileVersionInfoSize(filename *uint16, zeroHandle *Handle) (bufSize uint32, err error) {
|
||||
r0, _, e1 := syscall.Syscall(procGetFileVersionInfoSizeW.Addr(), 2, uintptr(unsafe.Pointer(filename)), uintptr(unsafe.Pointer(zeroHandle)), 0)
|
||||
bufSize = uint32(r0)
|
||||
if bufSize == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func GetFileVersionInfo(filename string, handle uint32, bufSize uint32, buffer unsafe.Pointer) (err error) {
|
||||
var _p0 *uint16
|
||||
_p0, err = syscall.UTF16PtrFromString(filename)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return _GetFileVersionInfo(_p0, handle, bufSize, buffer)
|
||||
}
|
||||
|
||||
func _GetFileVersionInfo(filename *uint16, handle uint32, bufSize uint32, buffer unsafe.Pointer) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procGetFileVersionInfoW.Addr(), 4, uintptr(unsafe.Pointer(filename)), uintptr(handle), uintptr(bufSize), uintptr(buffer), 0, 0)
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func VerQueryValue(block unsafe.Pointer, subBlock string, pointerToBufferPointer unsafe.Pointer, bufSize *uint32) (err error) {
|
||||
var _p0 *uint16
|
||||
_p0, err = syscall.UTF16PtrFromString(subBlock)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return _VerQueryValue(block, _p0, pointerToBufferPointer, bufSize)
|
||||
}
|
||||
|
||||
func _VerQueryValue(block unsafe.Pointer, subBlock *uint16, pointerToBufferPointer unsafe.Pointer, bufSize *uint32) (err error) {
|
||||
r1, _, e1 := syscall.Syscall6(procVerQueryValueW.Addr(), 4, uintptr(block), uintptr(unsafe.Pointer(subBlock)), uintptr(pointerToBufferPointer), uintptr(unsafe.Pointer(bufSize)), 0, 0)
|
||||
if r1 == 0 {
|
||||
err = errnoErr(e1)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func WinVerifyTrustEx(hwnd HWND, actionId *GUID, data *WinTrustData) (ret error) {
|
||||
r0, _, _ := syscall.Syscall(procWinVerifyTrustEx.Addr(), 3, uintptr(hwnd), uintptr(unsafe.Pointer(actionId)), uintptr(unsafe.Pointer(data)))
|
||||
if r0 != 0 {
|
||||
|
|
|
@ -546,7 +546,7 @@ golang.org/x/mod/internal/lazyregexp
|
|||
golang.org/x/mod/modfile
|
||||
golang.org/x/mod/module
|
||||
golang.org/x/mod/semver
|
||||
# golang.org/x/net v0.0.0-20211008194852-3b03d305991f
|
||||
# golang.org/x/net v0.0.0-20211104170005-ce137452f963
|
||||
## explicit; go 1.17
|
||||
golang.org/x/net/bpf
|
||||
golang.org/x/net/http/httpguts
|
||||
|
@ -559,7 +559,7 @@ golang.org/x/net/internal/socks
|
|||
golang.org/x/net/ipv4
|
||||
golang.org/x/net/ipv6
|
||||
golang.org/x/net/proxy
|
||||
# golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac
|
||||
# golang.org/x/sys v0.0.0-20211103235746-7861aae1554b
|
||||
## explicit; go 1.17
|
||||
golang.org/x/sys/cpu
|
||||
golang.org/x/sys/execabs
|
||||
|
|
Loading…
Reference in New Issue