Merge pull request #1519 from dexidp/sr/bump-deps-for-http2-issues

bump deps for http2 issues

https://github.com/grpc/grpc-go/releases/tag/v1.23.0

https://groups.google.com/forum/#!topic/golang-nuts/fCQWxqxP8aA
This commit is contained in:
Stephan Renatus 2019-08-14 11:33:54 +02:00 committed by GitHub
commit aeb2861a40
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
53 changed files with 462 additions and 296 deletions

View file

@ -1,4 +1,4 @@
FROM golang:1.12.4-alpine FROM golang:1.12.8-alpine
RUN apk add --no-cache --update alpine-sdk RUN apk add --no-cache --update alpine-sdk

10
go.mod
View file

@ -47,14 +47,14 @@ require (
go.uber.org/zap v1.10.0 // indirect go.uber.org/zap v1.10.0 // indirect
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4
golang.org/x/lint v0.0.0-20190409202823-959b441ac422 golang.org/x/lint v0.0.0-20190409202823-959b441ac422
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
golang.org/x/sys v0.0.0-20190730183949-1393eb018365 // indirect golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a // indirect
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect
golang.org/x/tools v0.0.0-20190730215328-ed3277de2799 // indirect golang.org/x/tools v0.0.0-20190813214729-9dba7caff850 // indirect
google.golang.org/appengine v1.6.1 // indirect google.golang.org/appengine v1.6.1 // indirect
google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610 // indirect google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64 // indirect
google.golang.org/grpc v1.22.1 google.golang.org/grpc v1.23.0
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d // indirect gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d // indirect
gopkg.in/ldap.v2 v2.5.1 gopkg.in/ldap.v2 v2.5.1
gopkg.in/square/go-jose.v2 v2.3.1 gopkg.in/square/go-jose.v2 v2.3.1

21
go.sum
View file

@ -195,8 +195,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 h1:Ao/3l156eZf2AW5wK8a7/smtodRU+gha3+BeqJ69lRk= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7 h1:fHDIZ2oxGnUZRN6WgWFCbYBjH9uqVPRCUVUDhs0wnbA=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -214,8 +214,8 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190730183949-1393eb018365 h1:SaXEMXhWzMJThc05vu6uh61Q245r4KaWMrsTedk0FDc= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a h1:aYOabOQFp6Vj6W1F80affTUvO9UxmJRx8K0gsfABByQ=
golang.org/x/sys v0.0.0-20190730183949-1393eb018365/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
@ -228,18 +228,19 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190730215328-ed3277de2799 h1:rvNf5qrBjmtxebJHK+blZSkGIv+Yg6UlDnl2ApkB6m4= golang.org/x/tools v0.0.0-20190813214729-9dba7caff850 h1:I+2i9HEjvv+3iJrNMhjMJOMF/FXz9eI08iBlDF4w24I=
golang.org/x/tools v0.0.0-20190730215328-ed3277de2799/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= golang.org/x/tools v0.0.0-20190813214729-9dba7caff850/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I= google.golang.org/appengine v1.6.1 h1:QzqyMA1tlu6CgqCDUtU9V+ZKhLFT2dkJuANu5QaxI3I=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610 h1:Ygq9/SRJX9+dU0WCIICM8RkWvDw03lvB77hrhJnpxfU= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64 h1:iKtrH9Y8mcbADOP0YFaEMth7OfuHY9xHOwNj4znpM1A=
google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.22.1 h1:/7cs52RnTJmD43s3uxzlq2U7nqVTd/37viQwMrMNlOM= google.golang.org/grpc v1.23.0 h1:AzbTB6ux+okLTzP8Ru1Xs41C303zdcfEht7MQnYJt5A=
google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d h1:TxyelI5cVkbREznMhfzycHdkp5cLA7DpE+GKjSslYhM= gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d h1:TxyelI5cVkbREznMhfzycHdkp5cLA7DpE+GKjSslYhM=
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=

View file

@ -52,10 +52,11 @@ import (
) )
const ( const (
prefaceTimeout = 10 * time.Second prefaceTimeout = 10 * time.Second
firstSettingsTimeout = 2 * time.Second // should be in-flight with preface anyway firstSettingsTimeout = 2 * time.Second // should be in-flight with preface anyway
handlerChunkWriteSize = 4 << 10 handlerChunkWriteSize = 4 << 10
defaultMaxStreams = 250 // TODO: make this 100 as the GFE seems to? defaultMaxStreams = 250 // TODO: make this 100 as the GFE seems to?
maxQueuedControlFrames = 10000
) )
var ( var (
@ -163,6 +164,15 @@ func (s *Server) maxConcurrentStreams() uint32 {
return defaultMaxStreams return defaultMaxStreams
} }
// maxQueuedControlFrames is the maximum number of control frames like
// SETTINGS, PING and RST_STREAM that will be queued for writing before
// the connection is closed to prevent memory exhaustion attacks.
func (s *Server) maxQueuedControlFrames() int {
// TODO: if anybody asks, add a Server field, and remember to define the
// behavior of negative values.
return maxQueuedControlFrames
}
type serverInternalState struct { type serverInternalState struct {
mu sync.Mutex mu sync.Mutex
activeConns map[*serverConn]struct{} activeConns map[*serverConn]struct{}
@ -506,6 +516,7 @@ type serverConn struct {
sawFirstSettings bool // got the initial SETTINGS frame after the preface sawFirstSettings bool // got the initial SETTINGS frame after the preface
needToSendSettingsAck bool needToSendSettingsAck bool
unackedSettings int // how many SETTINGS have we sent without ACKs? unackedSettings int // how many SETTINGS have we sent without ACKs?
queuedControlFrames int // control frames in the writeSched queue
clientMaxStreams uint32 // SETTINGS_MAX_CONCURRENT_STREAMS from client (our PUSH_PROMISE limit) clientMaxStreams uint32 // SETTINGS_MAX_CONCURRENT_STREAMS from client (our PUSH_PROMISE limit)
advMaxStreams uint32 // our SETTINGS_MAX_CONCURRENT_STREAMS advertised the client advMaxStreams uint32 // our SETTINGS_MAX_CONCURRENT_STREAMS advertised the client
curClientStreams uint32 // number of open streams initiated by the client curClientStreams uint32 // number of open streams initiated by the client
@ -894,6 +905,14 @@ func (sc *serverConn) serve() {
} }
} }
// If the peer is causing us to generate a lot of control frames,
// but not reading them from us, assume they are trying to make us
// run out of memory.
if sc.queuedControlFrames > sc.srv.maxQueuedControlFrames() {
sc.vlogf("http2: too many control frames in send queue, closing connection")
return
}
// Start the shutdown timer after sending a GOAWAY. When sending GOAWAY // Start the shutdown timer after sending a GOAWAY. When sending GOAWAY
// with no error code (graceful shutdown), don't start the timer until // with no error code (graceful shutdown), don't start the timer until
// all open streams have been completed. // all open streams have been completed.
@ -1093,6 +1112,14 @@ func (sc *serverConn) writeFrame(wr FrameWriteRequest) {
} }
if !ignoreWrite { if !ignoreWrite {
if wr.isControl() {
sc.queuedControlFrames++
// For extra safety, detect wraparounds, which should not happen,
// and pull the plug.
if sc.queuedControlFrames < 0 {
sc.conn.Close()
}
}
sc.writeSched.Push(wr) sc.writeSched.Push(wr)
} }
sc.scheduleFrameWrite() sc.scheduleFrameWrite()
@ -1210,10 +1237,8 @@ func (sc *serverConn) wroteFrame(res frameWriteResult) {
// If a frame is already being written, nothing happens. This will be called again // If a frame is already being written, nothing happens. This will be called again
// when the frame is done being written. // when the frame is done being written.
// //
// If a frame isn't being written we need to send one, the best frame // If a frame isn't being written and we need to send one, the best frame
// to send is selected, preferring first things that aren't // to send is selected by writeSched.
// stream-specific (e.g. ACKing settings), and then finding the
// highest priority stream.
// //
// If a frame isn't being written and there's nothing else to send, we // If a frame isn't being written and there's nothing else to send, we
// flush the write buffer. // flush the write buffer.
@ -1241,6 +1266,9 @@ func (sc *serverConn) scheduleFrameWrite() {
} }
if !sc.inGoAway || sc.goAwayCode == ErrCodeNo { if !sc.inGoAway || sc.goAwayCode == ErrCodeNo {
if wr, ok := sc.writeSched.Pop(); ok { if wr, ok := sc.writeSched.Pop(); ok {
if wr.isControl() {
sc.queuedControlFrames--
}
sc.startFrameWrite(wr) sc.startFrameWrite(wr)
continue continue
} }
@ -1533,6 +1561,8 @@ func (sc *serverConn) processSettings(f *SettingsFrame) error {
if err := f.ForeachSetting(sc.processSetting); err != nil { if err := f.ForeachSetting(sc.processSetting); err != nil {
return err return err
} }
// TODO: judging by RFC 7540, Section 6.5.3 each SETTINGS frame should be
// acknowledged individually, even if multiple are received before the ACK.
sc.needToSendSettingsAck = true sc.needToSendSettingsAck = true
sc.scheduleFrameWrite() sc.scheduleFrameWrite()
return nil return nil

View file

@ -32,7 +32,7 @@ type WriteScheduler interface {
// Pop dequeues the next frame to write. Returns false if no frames can // Pop dequeues the next frame to write. Returns false if no frames can
// be written. Frames with a given wr.StreamID() are Pop'd in the same // be written. Frames with a given wr.StreamID() are Pop'd in the same
// order they are Push'd. // order they are Push'd. No frames should be discarded except by CloseStream.
Pop() (wr FrameWriteRequest, ok bool) Pop() (wr FrameWriteRequest, ok bool)
} }
@ -76,6 +76,12 @@ func (wr FrameWriteRequest) StreamID() uint32 {
return wr.stream.id return wr.stream.id
} }
// isControl reports whether wr is a control frame for MaxQueuedControlFrames
// purposes. That includes non-stream frames and RST_STREAM frames.
func (wr FrameWriteRequest) isControl() bool {
return wr.stream == nil
}
// DataSize returns the number of flow control bytes that must be consumed // DataSize returns the number of flow control bytes that must be consumed
// to write this entire frame. This is 0 for non-DATA frames. // to write this entire frame. This is 0 for non-DATA frames.
func (wr FrameWriteRequest) DataSize() int { func (wr FrameWriteRequest) DataSize() int {

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
// +build aix darwin dragonfly freebsd linux nacl netbsd openbsd solaris // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
package unix package unix

View file

@ -89,7 +89,6 @@ func direntNamlen(buf []byte) (uint64, bool) {
return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen)) return readInt(buf, unsafe.Offsetof(Dirent{}.Namlen), unsafe.Sizeof(Dirent{}.Namlen))
} }
//sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error)
func PtraceAttach(pid int) (err error) { return ptrace(PT_ATTACH, pid, 0, 0) } func PtraceAttach(pid int) (err error) { return ptrace(PT_ATTACH, pid, 0, 0) }
func PtraceDetach(pid int) (err error) { return ptrace(PT_DETACH, pid, 0, 0) } func PtraceDetach(pid int) (err error) { return ptrace(PT_DETACH, pid, 0, 0) }

View file

@ -10,6 +10,8 @@ import (
"syscall" "syscall"
) )
//sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error)
func setTimespec(sec, nsec int64) Timespec { func setTimespec(sec, nsec int64) Timespec {
return Timespec{Sec: int32(sec), Nsec: int32(nsec)} return Timespec{Sec: int32(sec), Nsec: int32(nsec)}
} }

View file

@ -10,6 +10,8 @@ import (
"syscall" "syscall"
) )
//sys ptrace(request int, pid int, addr uintptr, data uintptr) (err error)
func setTimespec(sec, nsec int64) Timespec { func setTimespec(sec, nsec int64) Timespec {
return Timespec{Sec: sec, Nsec: nsec} return Timespec{Sec: sec, Nsec: nsec}
} }

View file

@ -8,6 +8,10 @@ import (
"syscall" "syscall"
) )
func ptrace(request int, pid int, addr uintptr, data uintptr) error {
return ENOTSUP
}
func setTimespec(sec, nsec int64) Timespec { func setTimespec(sec, nsec int64) Timespec {
return Timespec{Sec: int32(sec), Nsec: int32(nsec)} return Timespec{Sec: int32(sec), Nsec: int32(nsec)}
} }

View file

@ -10,6 +10,10 @@ import (
"syscall" "syscall"
) )
func ptrace(request int, pid int, addr uintptr, data uintptr) error {
return ENOTSUP
}
func setTimespec(sec, nsec int64) Timespec { func setTimespec(sec, nsec int64) Timespec {
return Timespec{Sec: sec, Nsec: nsec} return Timespec{Sec: sec, Nsec: nsec}
} }

View file

@ -722,6 +722,7 @@ const (
F_OFD_SETLKW = 0x26 F_OFD_SETLKW = 0x26
F_OK = 0x0 F_OK = 0x0
F_RDLCK = 0x0 F_RDLCK = 0x0
F_SEAL_FUTURE_WRITE = 0x10
F_SEAL_GROW = 0x4 F_SEAL_GROW = 0x4
F_SEAL_SEAL = 0x1 F_SEAL_SEAL = 0x1
F_SEAL_SHRINK = 0x2 F_SEAL_SHRINK = 0x2
@ -987,6 +988,7 @@ const (
IPV6_RECVRTHDR = 0x38 IPV6_RECVRTHDR = 0x38
IPV6_RECVTCLASS = 0x42 IPV6_RECVTCLASS = 0x42
IPV6_ROUTER_ALERT = 0x16 IPV6_ROUTER_ALERT = 0x16
IPV6_ROUTER_ALERT_ISOLATE = 0x1e
IPV6_RTHDR = 0x39 IPV6_RTHDR = 0x39
IPV6_RTHDRDSTOPTS = 0x37 IPV6_RTHDRDSTOPTS = 0x37
IPV6_RTHDR_LOOSE = 0x0 IPV6_RTHDR_LOOSE = 0x0

View file

@ -722,6 +722,7 @@ const (
F_OFD_SETLKW = 0x26 F_OFD_SETLKW = 0x26
F_OK = 0x0 F_OK = 0x0
F_RDLCK = 0x0 F_RDLCK = 0x0
F_SEAL_FUTURE_WRITE = 0x10
F_SEAL_GROW = 0x4 F_SEAL_GROW = 0x4
F_SEAL_SEAL = 0x1 F_SEAL_SEAL = 0x1
F_SEAL_SHRINK = 0x2 F_SEAL_SHRINK = 0x2
@ -987,6 +988,7 @@ const (
IPV6_RECVRTHDR = 0x38 IPV6_RECVRTHDR = 0x38
IPV6_RECVTCLASS = 0x42 IPV6_RECVTCLASS = 0x42
IPV6_ROUTER_ALERT = 0x16 IPV6_ROUTER_ALERT = 0x16
IPV6_ROUTER_ALERT_ISOLATE = 0x1e
IPV6_RTHDR = 0x39 IPV6_RTHDR = 0x39
IPV6_RTHDRDSTOPTS = 0x37 IPV6_RTHDRDSTOPTS = 0x37
IPV6_RTHDR_LOOSE = 0x0 IPV6_RTHDR_LOOSE = 0x0

View file

@ -721,6 +721,7 @@ const (
F_OFD_SETLKW = 0x26 F_OFD_SETLKW = 0x26
F_OK = 0x0 F_OK = 0x0
F_RDLCK = 0x0 F_RDLCK = 0x0
F_SEAL_FUTURE_WRITE = 0x10
F_SEAL_GROW = 0x4 F_SEAL_GROW = 0x4
F_SEAL_SEAL = 0x1 F_SEAL_SEAL = 0x1
F_SEAL_SHRINK = 0x2 F_SEAL_SHRINK = 0x2
@ -986,6 +987,7 @@ const (
IPV6_RECVRTHDR = 0x38 IPV6_RECVRTHDR = 0x38
IPV6_RECVTCLASS = 0x42 IPV6_RECVTCLASS = 0x42
IPV6_ROUTER_ALERT = 0x16 IPV6_ROUTER_ALERT = 0x16
IPV6_ROUTER_ALERT_ISOLATE = 0x1e
IPV6_RTHDR = 0x39 IPV6_RTHDR = 0x39
IPV6_RTHDRDSTOPTS = 0x37 IPV6_RTHDRDSTOPTS = 0x37
IPV6_RTHDR_LOOSE = 0x0 IPV6_RTHDR_LOOSE = 0x0

View file

@ -724,6 +724,7 @@ const (
F_OFD_SETLKW = 0x26 F_OFD_SETLKW = 0x26
F_OK = 0x0 F_OK = 0x0
F_RDLCK = 0x0 F_RDLCK = 0x0
F_SEAL_FUTURE_WRITE = 0x10
F_SEAL_GROW = 0x4 F_SEAL_GROW = 0x4
F_SEAL_SEAL = 0x1 F_SEAL_SEAL = 0x1
F_SEAL_SHRINK = 0x2 F_SEAL_SHRINK = 0x2
@ -989,6 +990,7 @@ const (
IPV6_RECVRTHDR = 0x38 IPV6_RECVRTHDR = 0x38
IPV6_RECVTCLASS = 0x42 IPV6_RECVTCLASS = 0x42
IPV6_ROUTER_ALERT = 0x16 IPV6_ROUTER_ALERT = 0x16
IPV6_ROUTER_ALERT_ISOLATE = 0x1e
IPV6_RTHDR = 0x39 IPV6_RTHDR = 0x39
IPV6_RTHDRDSTOPTS = 0x37 IPV6_RTHDRDSTOPTS = 0x37
IPV6_RTHDR_LOOSE = 0x0 IPV6_RTHDR_LOOSE = 0x0

View file

@ -721,6 +721,7 @@ const (
F_OFD_SETLKW = 0x26 F_OFD_SETLKW = 0x26
F_OK = 0x0 F_OK = 0x0
F_RDLCK = 0x0 F_RDLCK = 0x0
F_SEAL_FUTURE_WRITE = 0x10
F_SEAL_GROW = 0x4 F_SEAL_GROW = 0x4
F_SEAL_SEAL = 0x1 F_SEAL_SEAL = 0x1
F_SEAL_SHRINK = 0x2 F_SEAL_SHRINK = 0x2
@ -986,6 +987,7 @@ const (
IPV6_RECVRTHDR = 0x38 IPV6_RECVRTHDR = 0x38
IPV6_RECVTCLASS = 0x42 IPV6_RECVTCLASS = 0x42
IPV6_ROUTER_ALERT = 0x16 IPV6_ROUTER_ALERT = 0x16
IPV6_ROUTER_ALERT_ISOLATE = 0x1e
IPV6_RTHDR = 0x39 IPV6_RTHDR = 0x39
IPV6_RTHDRDSTOPTS = 0x37 IPV6_RTHDRDSTOPTS = 0x37
IPV6_RTHDR_LOOSE = 0x0 IPV6_RTHDR_LOOSE = 0x0

View file

@ -721,6 +721,7 @@ const (
F_OFD_SETLKW = 0x26 F_OFD_SETLKW = 0x26
F_OK = 0x0 F_OK = 0x0
F_RDLCK = 0x0 F_RDLCK = 0x0
F_SEAL_FUTURE_WRITE = 0x10
F_SEAL_GROW = 0x4 F_SEAL_GROW = 0x4
F_SEAL_SEAL = 0x1 F_SEAL_SEAL = 0x1
F_SEAL_SHRINK = 0x2 F_SEAL_SHRINK = 0x2
@ -986,6 +987,7 @@ const (
IPV6_RECVRTHDR = 0x38 IPV6_RECVRTHDR = 0x38
IPV6_RECVTCLASS = 0x42 IPV6_RECVTCLASS = 0x42
IPV6_ROUTER_ALERT = 0x16 IPV6_ROUTER_ALERT = 0x16
IPV6_ROUTER_ALERT_ISOLATE = 0x1e
IPV6_RTHDR = 0x39 IPV6_RTHDR = 0x39
IPV6_RTHDRDSTOPTS = 0x37 IPV6_RTHDRDSTOPTS = 0x37
IPV6_RTHDR_LOOSE = 0x0 IPV6_RTHDR_LOOSE = 0x0

View file

@ -721,6 +721,7 @@ const (
F_OFD_SETLKW = 0x26 F_OFD_SETLKW = 0x26
F_OK = 0x0 F_OK = 0x0
F_RDLCK = 0x0 F_RDLCK = 0x0
F_SEAL_FUTURE_WRITE = 0x10
F_SEAL_GROW = 0x4 F_SEAL_GROW = 0x4
F_SEAL_SEAL = 0x1 F_SEAL_SEAL = 0x1
F_SEAL_SHRINK = 0x2 F_SEAL_SHRINK = 0x2
@ -986,6 +987,7 @@ const (
IPV6_RECVRTHDR = 0x38 IPV6_RECVRTHDR = 0x38
IPV6_RECVTCLASS = 0x42 IPV6_RECVTCLASS = 0x42
IPV6_ROUTER_ALERT = 0x16 IPV6_ROUTER_ALERT = 0x16
IPV6_ROUTER_ALERT_ISOLATE = 0x1e
IPV6_RTHDR = 0x39 IPV6_RTHDR = 0x39
IPV6_RTHDRDSTOPTS = 0x37 IPV6_RTHDRDSTOPTS = 0x37
IPV6_RTHDR_LOOSE = 0x0 IPV6_RTHDR_LOOSE = 0x0

View file

@ -721,6 +721,7 @@ const (
F_OFD_SETLKW = 0x26 F_OFD_SETLKW = 0x26
F_OK = 0x0 F_OK = 0x0
F_RDLCK = 0x0 F_RDLCK = 0x0
F_SEAL_FUTURE_WRITE = 0x10
F_SEAL_GROW = 0x4 F_SEAL_GROW = 0x4
F_SEAL_SEAL = 0x1 F_SEAL_SEAL = 0x1
F_SEAL_SHRINK = 0x2 F_SEAL_SHRINK = 0x2
@ -986,6 +987,7 @@ const (
IPV6_RECVRTHDR = 0x38 IPV6_RECVRTHDR = 0x38
IPV6_RECVTCLASS = 0x42 IPV6_RECVTCLASS = 0x42
IPV6_ROUTER_ALERT = 0x16 IPV6_ROUTER_ALERT = 0x16
IPV6_ROUTER_ALERT_ISOLATE = 0x1e
IPV6_RTHDR = 0x39 IPV6_RTHDR = 0x39
IPV6_RTHDRDSTOPTS = 0x37 IPV6_RTHDRDSTOPTS = 0x37
IPV6_RTHDR_LOOSE = 0x0 IPV6_RTHDR_LOOSE = 0x0

View file

@ -721,6 +721,7 @@ const (
F_OFD_SETLKW = 0x26 F_OFD_SETLKW = 0x26
F_OK = 0x0 F_OK = 0x0
F_RDLCK = 0x0 F_RDLCK = 0x0
F_SEAL_FUTURE_WRITE = 0x10
F_SEAL_GROW = 0x4 F_SEAL_GROW = 0x4
F_SEAL_SEAL = 0x1 F_SEAL_SEAL = 0x1
F_SEAL_SHRINK = 0x2 F_SEAL_SHRINK = 0x2
@ -986,6 +987,7 @@ const (
IPV6_RECVRTHDR = 0x38 IPV6_RECVRTHDR = 0x38
IPV6_RECVTCLASS = 0x42 IPV6_RECVTCLASS = 0x42
IPV6_ROUTER_ALERT = 0x16 IPV6_ROUTER_ALERT = 0x16
IPV6_ROUTER_ALERT_ISOLATE = 0x1e
IPV6_RTHDR = 0x39 IPV6_RTHDR = 0x39
IPV6_RTHDRDSTOPTS = 0x37 IPV6_RTHDRDSTOPTS = 0x37
IPV6_RTHDR_LOOSE = 0x0 IPV6_RTHDR_LOOSE = 0x0

View file

@ -721,6 +721,7 @@ const (
F_OFD_SETLKW = 0x26 F_OFD_SETLKW = 0x26
F_OK = 0x0 F_OK = 0x0
F_RDLCK = 0x0 F_RDLCK = 0x0
F_SEAL_FUTURE_WRITE = 0x10
F_SEAL_GROW = 0x4 F_SEAL_GROW = 0x4
F_SEAL_SEAL = 0x1 F_SEAL_SEAL = 0x1
F_SEAL_SHRINK = 0x2 F_SEAL_SHRINK = 0x2
@ -986,6 +987,7 @@ const (
IPV6_RECVRTHDR = 0x38 IPV6_RECVRTHDR = 0x38
IPV6_RECVTCLASS = 0x42 IPV6_RECVTCLASS = 0x42
IPV6_ROUTER_ALERT = 0x16 IPV6_ROUTER_ALERT = 0x16
IPV6_ROUTER_ALERT_ISOLATE = 0x1e
IPV6_RTHDR = 0x39 IPV6_RTHDR = 0x39
IPV6_RTHDRDSTOPTS = 0x37 IPV6_RTHDRDSTOPTS = 0x37
IPV6_RTHDR_LOOSE = 0x0 IPV6_RTHDR_LOOSE = 0x0

View file

@ -721,6 +721,7 @@ const (
F_OFD_SETLKW = 0x26 F_OFD_SETLKW = 0x26
F_OK = 0x0 F_OK = 0x0
F_RDLCK = 0x0 F_RDLCK = 0x0
F_SEAL_FUTURE_WRITE = 0x10
F_SEAL_GROW = 0x4 F_SEAL_GROW = 0x4
F_SEAL_SEAL = 0x1 F_SEAL_SEAL = 0x1
F_SEAL_SHRINK = 0x2 F_SEAL_SHRINK = 0x2
@ -986,6 +987,7 @@ const (
IPV6_RECVRTHDR = 0x38 IPV6_RECVRTHDR = 0x38
IPV6_RECVTCLASS = 0x42 IPV6_RECVTCLASS = 0x42
IPV6_ROUTER_ALERT = 0x16 IPV6_ROUTER_ALERT = 0x16
IPV6_ROUTER_ALERT_ISOLATE = 0x1e
IPV6_RTHDR = 0x39 IPV6_RTHDR = 0x39
IPV6_RTHDRDSTOPTS = 0x37 IPV6_RTHDRDSTOPTS = 0x37
IPV6_RTHDR_LOOSE = 0x0 IPV6_RTHDR_LOOSE = 0x0

View file

@ -721,6 +721,7 @@ const (
F_OFD_SETLKW = 0x26 F_OFD_SETLKW = 0x26
F_OK = 0x0 F_OK = 0x0
F_RDLCK = 0x0 F_RDLCK = 0x0
F_SEAL_FUTURE_WRITE = 0x10
F_SEAL_GROW = 0x4 F_SEAL_GROW = 0x4
F_SEAL_SEAL = 0x1 F_SEAL_SEAL = 0x1
F_SEAL_SHRINK = 0x2 F_SEAL_SHRINK = 0x2
@ -986,6 +987,7 @@ const (
IPV6_RECVRTHDR = 0x38 IPV6_RECVRTHDR = 0x38
IPV6_RECVTCLASS = 0x42 IPV6_RECVTCLASS = 0x42
IPV6_ROUTER_ALERT = 0x16 IPV6_ROUTER_ALERT = 0x16
IPV6_ROUTER_ALERT_ISOLATE = 0x1e
IPV6_RTHDR = 0x39 IPV6_RTHDR = 0x39
IPV6_RTHDRDSTOPTS = 0x37 IPV6_RTHDRDSTOPTS = 0x37
IPV6_RTHDR_LOOSE = 0x0 IPV6_RTHDR_LOOSE = 0x0

View file

@ -725,6 +725,7 @@ const (
F_OFD_SETLKW = 0x26 F_OFD_SETLKW = 0x26
F_OK = 0x0 F_OK = 0x0
F_RDLCK = 0x1 F_RDLCK = 0x1
F_SEAL_FUTURE_WRITE = 0x10
F_SEAL_GROW = 0x4 F_SEAL_GROW = 0x4
F_SEAL_SEAL = 0x1 F_SEAL_SEAL = 0x1
F_SEAL_SHRINK = 0x2 F_SEAL_SHRINK = 0x2
@ -990,6 +991,7 @@ const (
IPV6_RECVRTHDR = 0x38 IPV6_RECVRTHDR = 0x38
IPV6_RECVTCLASS = 0x42 IPV6_RECVTCLASS = 0x42
IPV6_ROUTER_ALERT = 0x16 IPV6_ROUTER_ALERT = 0x16
IPV6_ROUTER_ALERT_ISOLATE = 0x1e
IPV6_RTHDR = 0x39 IPV6_RTHDR = 0x39
IPV6_RTHDRDSTOPTS = 0x37 IPV6_RTHDRDSTOPTS = 0x37
IPV6_RTHDR_LOOSE = 0x0 IPV6_RTHDR_LOOSE = 0x0

View file

@ -377,16 +377,6 @@ func Munlockall() (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
_, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func getattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error) { func getattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error) {
_, _, e1 := Syscall6(SYS_GETATTRLIST, uintptr(unsafe.Pointer(path)), uintptr(list), uintptr(buf), uintptr(size), uintptr(options), 0) _, _, e1 := Syscall6(SYS_GETATTRLIST, uintptr(unsafe.Pointer(path)), uintptr(list), uintptr(buf), uintptr(size), uintptr(options), 0)
if e1 != 0 { if e1 != 0 {
@ -1691,6 +1681,16 @@ func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
_, _, e1 := Syscall6(SYS_PTRACE, uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func gettimeofday(tp *Timeval) (sec int32, usec int32, err error) { func gettimeofday(tp *Timeval) (sec int32, usec int32, err error) {
r0, r1, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0) r0, r1, e1 := RawSyscall(SYS_GETTIMEOFDAY, uintptr(unsafe.Pointer(tp)), 0, 0)
sec = int32(r0) sec = int32(r0)

View file

@ -527,21 +527,6 @@ func libc_munlockall_trampoline()
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
_, _, e1 := syscall_syscall6(funcPC(libc_ptrace_trampoline), uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
func libc_ptrace_trampoline()
//go:linkname libc_ptrace libc_ptrace
//go:cgo_import_dynamic libc_ptrace ptrace "/usr/lib/libSystem.B.dylib"
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func getattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error) { func getattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error) {
_, _, e1 := syscall_syscall6(funcPC(libc_getattrlist_trampoline), uintptr(unsafe.Pointer(path)), uintptr(list), uintptr(buf), uintptr(size), uintptr(options), 0) _, _, e1 := syscall_syscall6(funcPC(libc_getattrlist_trampoline), uintptr(unsafe.Pointer(path)), uintptr(list), uintptr(buf), uintptr(size), uintptr(options), 0)
if e1 != 0 { if e1 != 0 {
@ -2341,6 +2326,21 @@ func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
_, _, e1 := syscall_syscall6(funcPC(libc_ptrace_trampoline), uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
func libc_ptrace_trampoline()
//go:linkname libc_ptrace libc_ptrace
//go:cgo_import_dynamic libc_ptrace ptrace "/usr/lib/libSystem.B.dylib"
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func gettimeofday(tp *Timeval) (sec int32, usec int32, err error) { func gettimeofday(tp *Timeval) (sec int32, usec int32, err error) {
r0, r1, e1 := syscall_rawSyscall(funcPC(libc_gettimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0) r0, r1, e1 := syscall_rawSyscall(funcPC(libc_gettimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0)
sec = int32(r0) sec = int32(r0)

View file

@ -64,8 +64,6 @@ TEXT ·libc_munlock_trampoline(SB),NOSPLIT,$0-0
JMP libc_munlock(SB) JMP libc_munlock(SB)
TEXT ·libc_munlockall_trampoline(SB),NOSPLIT,$0-0 TEXT ·libc_munlockall_trampoline(SB),NOSPLIT,$0-0
JMP libc_munlockall(SB) JMP libc_munlockall(SB)
TEXT ·libc_ptrace_trampoline(SB),NOSPLIT,$0-0
JMP libc_ptrace(SB)
TEXT ·libc_getattrlist_trampoline(SB),NOSPLIT,$0-0 TEXT ·libc_getattrlist_trampoline(SB),NOSPLIT,$0-0
JMP libc_getattrlist(SB) JMP libc_getattrlist(SB)
TEXT ·libc_pipe_trampoline(SB),NOSPLIT,$0-0 TEXT ·libc_pipe_trampoline(SB),NOSPLIT,$0-0
@ -264,6 +262,8 @@ TEXT ·libc_mmap_trampoline(SB),NOSPLIT,$0-0
JMP libc_mmap(SB) JMP libc_mmap(SB)
TEXT ·libc_munmap_trampoline(SB),NOSPLIT,$0-0 TEXT ·libc_munmap_trampoline(SB),NOSPLIT,$0-0
JMP libc_munmap(SB) JMP libc_munmap(SB)
TEXT ·libc_ptrace_trampoline(SB),NOSPLIT,$0-0
JMP libc_ptrace(SB)
TEXT ·libc_gettimeofday_trampoline(SB),NOSPLIT,$0-0 TEXT ·libc_gettimeofday_trampoline(SB),NOSPLIT,$0-0
JMP libc_gettimeofday(SB) JMP libc_gettimeofday(SB)
TEXT ·libc_fstat64_trampoline(SB),NOSPLIT,$0-0 TEXT ·libc_fstat64_trampoline(SB),NOSPLIT,$0-0

View file

@ -527,21 +527,6 @@ func libc_munlockall_trampoline()
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
_, _, e1 := syscall_syscall6(funcPC(libc_ptrace_trampoline), uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
func libc_ptrace_trampoline()
//go:linkname libc_ptrace libc_ptrace
//go:cgo_import_dynamic libc_ptrace ptrace "/usr/lib/libSystem.B.dylib"
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func getattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error) { func getattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error) {
_, _, e1 := syscall_syscall6(funcPC(libc_getattrlist_trampoline), uintptr(unsafe.Pointer(path)), uintptr(list), uintptr(buf), uintptr(size), uintptr(options), 0) _, _, e1 := syscall_syscall6(funcPC(libc_getattrlist_trampoline), uintptr(unsafe.Pointer(path)), uintptr(list), uintptr(buf), uintptr(size), uintptr(options), 0)
if e1 != 0 { if e1 != 0 {
@ -2356,6 +2341,21 @@ func writelen(fd int, buf *byte, nbuf int) (n int, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
_, _, e1 := syscall_syscall6(funcPC(libc_ptrace_trampoline), uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
func libc_ptrace_trampoline()
//go:linkname libc_ptrace libc_ptrace
//go:cgo_import_dynamic libc_ptrace ptrace "/usr/lib/libSystem.B.dylib"
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func gettimeofday(tp *Timeval) (sec int64, usec int32, err error) { func gettimeofday(tp *Timeval) (sec int64, usec int32, err error) {
r0, r1, e1 := syscall_rawSyscall(funcPC(libc_gettimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0) r0, r1, e1 := syscall_rawSyscall(funcPC(libc_gettimeofday_trampoline), uintptr(unsafe.Pointer(tp)), 0, 0)
sec = int64(r0) sec = int64(r0)

View file

@ -64,8 +64,6 @@ TEXT ·libc_munlock_trampoline(SB),NOSPLIT,$0-0
JMP libc_munlock(SB) JMP libc_munlock(SB)
TEXT ·libc_munlockall_trampoline(SB),NOSPLIT,$0-0 TEXT ·libc_munlockall_trampoline(SB),NOSPLIT,$0-0
JMP libc_munlockall(SB) JMP libc_munlockall(SB)
TEXT ·libc_ptrace_trampoline(SB),NOSPLIT,$0-0
JMP libc_ptrace(SB)
TEXT ·libc_getattrlist_trampoline(SB),NOSPLIT,$0-0 TEXT ·libc_getattrlist_trampoline(SB),NOSPLIT,$0-0
JMP libc_getattrlist(SB) JMP libc_getattrlist(SB)
TEXT ·libc_pipe_trampoline(SB),NOSPLIT,$0-0 TEXT ·libc_pipe_trampoline(SB),NOSPLIT,$0-0
@ -266,6 +264,8 @@ TEXT ·libc_mmap_trampoline(SB),NOSPLIT,$0-0
JMP libc_mmap(SB) JMP libc_mmap(SB)
TEXT ·libc_munmap_trampoline(SB),NOSPLIT,$0-0 TEXT ·libc_munmap_trampoline(SB),NOSPLIT,$0-0
JMP libc_munmap(SB) JMP libc_munmap(SB)
TEXT ·libc_ptrace_trampoline(SB),NOSPLIT,$0-0
JMP libc_ptrace(SB)
TEXT ·libc_gettimeofday_trampoline(SB),NOSPLIT,$0-0 TEXT ·libc_gettimeofday_trampoline(SB),NOSPLIT,$0-0
JMP libc_gettimeofday(SB) JMP libc_gettimeofday(SB)
TEXT ·libc_fstat64_trampoline(SB),NOSPLIT,$0-0 TEXT ·libc_fstat64_trampoline(SB),NOSPLIT,$0-0

View file

@ -527,21 +527,6 @@ func libc_munlockall_trampoline()
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
_, _, e1 := syscall_syscall6(funcPC(libc_ptrace_trampoline), uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
func libc_ptrace_trampoline()
//go:linkname libc_ptrace libc_ptrace
//go:cgo_import_dynamic libc_ptrace ptrace "/usr/lib/libSystem.B.dylib"
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func getattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error) { func getattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error) {
_, _, e1 := syscall_syscall6(funcPC(libc_getattrlist_trampoline), uintptr(unsafe.Pointer(path)), uintptr(list), uintptr(buf), uintptr(size), uintptr(options), 0) _, _, e1 := syscall_syscall6(funcPC(libc_getattrlist_trampoline), uintptr(unsafe.Pointer(path)), uintptr(list), uintptr(buf), uintptr(size), uintptr(options), 0)
if e1 != 0 { if e1 != 0 {

View file

@ -64,8 +64,6 @@ TEXT ·libc_munlock_trampoline(SB),NOSPLIT,$0-0
JMP libc_munlock(SB) JMP libc_munlock(SB)
TEXT ·libc_munlockall_trampoline(SB),NOSPLIT,$0-0 TEXT ·libc_munlockall_trampoline(SB),NOSPLIT,$0-0
JMP libc_munlockall(SB) JMP libc_munlockall(SB)
TEXT ·libc_ptrace_trampoline(SB),NOSPLIT,$0-0
JMP libc_ptrace(SB)
TEXT ·libc_getattrlist_trampoline(SB),NOSPLIT,$0-0 TEXT ·libc_getattrlist_trampoline(SB),NOSPLIT,$0-0
JMP libc_getattrlist(SB) JMP libc_getattrlist(SB)
TEXT ·libc_pipe_trampoline(SB),NOSPLIT,$0-0 TEXT ·libc_pipe_trampoline(SB),NOSPLIT,$0-0

View file

@ -527,21 +527,6 @@ func libc_munlockall_trampoline()
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func ptrace(request int, pid int, addr uintptr, data uintptr) (err error) {
_, _, e1 := syscall_syscall6(funcPC(libc_ptrace_trampoline), uintptr(request), uintptr(pid), uintptr(addr), uintptr(data), 0, 0)
if e1 != 0 {
err = errnoErr(e1)
}
return
}
func libc_ptrace_trampoline()
//go:linkname libc_ptrace libc_ptrace
//go:cgo_import_dynamic libc_ptrace ptrace "/usr/lib/libSystem.B.dylib"
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
func getattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error) { func getattrlist(path *byte, list unsafe.Pointer, buf unsafe.Pointer, size uintptr, options int) (err error) {
_, _, e1 := syscall_syscall6(funcPC(libc_getattrlist_trampoline), uintptr(unsafe.Pointer(path)), uintptr(list), uintptr(buf), uintptr(size), uintptr(options), 0) _, _, e1 := syscall_syscall6(funcPC(libc_getattrlist_trampoline), uintptr(unsafe.Pointer(path)), uintptr(list), uintptr(buf), uintptr(size), uintptr(options), 0)
if e1 != 0 { if e1 != 0 {

View file

@ -64,8 +64,6 @@ TEXT ·libc_munlock_trampoline(SB),NOSPLIT,$0-0
JMP libc_munlock(SB) JMP libc_munlock(SB)
TEXT ·libc_munlockall_trampoline(SB),NOSPLIT,$0-0 TEXT ·libc_munlockall_trampoline(SB),NOSPLIT,$0-0
JMP libc_munlockall(SB) JMP libc_munlockall(SB)
TEXT ·libc_ptrace_trampoline(SB),NOSPLIT,$0-0
JMP libc_ptrace(SB)
TEXT ·libc_getattrlist_trampoline(SB),NOSPLIT,$0-0 TEXT ·libc_getattrlist_trampoline(SB),NOSPLIT,$0-0
JMP libc_getattrlist(SB) JMP libc_getattrlist(SB)
TEXT ·libc_pipe_trampoline(SB),NOSPLIT,$0-0 TEXT ·libc_pipe_trampoline(SB),NOSPLIT,$0-0

View file

@ -808,6 +808,7 @@ type Ustat_t struct {
type EpollEvent struct { type EpollEvent struct {
Events uint32 Events uint32
_ int32
Fd int32 Fd int32
Pad int32 Pad int32
} }

View file

@ -159,6 +159,10 @@ type SERVICE_DESCRIPTION struct {
Description *uint16 Description *uint16
} }
type SERVICE_DELAYED_AUTO_START_INFO struct {
IsDelayedAutoStartUp uint32
}
type SERVICE_STATUS_PROCESS struct { type SERVICE_STATUS_PROCESS struct {
ServiceType uint32 ServiceType uint32
CurrentState uint32 CurrentState uint32

View file

@ -43,7 +43,7 @@ type Address struct {
// BalancerConfig specifies the configurations for Balancer. // BalancerConfig specifies the configurations for Balancer.
// //
// Deprecated: please use package balancer. // Deprecated: please use package balancer. May be removed in a future 1.x release.
type BalancerConfig struct { type BalancerConfig struct {
// DialCreds is the transport credential the Balancer implementation can // DialCreds is the transport credential the Balancer implementation can
// use to dial to a remote load balancer server. The Balancer implementations // use to dial to a remote load balancer server. The Balancer implementations
@ -57,7 +57,7 @@ type BalancerConfig struct {
// BalancerGetOptions configures a Get call. // BalancerGetOptions configures a Get call.
// //
// Deprecated: please use package balancer. // Deprecated: please use package balancer. May be removed in a future 1.x release.
type BalancerGetOptions struct { type BalancerGetOptions struct {
// BlockingWait specifies whether Get should block when there is no // BlockingWait specifies whether Get should block when there is no
// connected address. // connected address.
@ -66,7 +66,7 @@ type BalancerGetOptions struct {
// Balancer chooses network addresses for RPCs. // Balancer chooses network addresses for RPCs.
// //
// Deprecated: please use package balancer. // Deprecated: please use package balancer. May be removed in a future 1.x release.
type Balancer interface { type Balancer interface {
// Start does the initialization work to bootstrap a Balancer. For example, // Start does the initialization work to bootstrap a Balancer. For example,
// this function may start the name resolution and watch the updates. It will // this function may start the name resolution and watch the updates. It will
@ -120,7 +120,7 @@ type Balancer interface {
// RoundRobin returns a Balancer that selects addresses round-robin. It uses r to watch // RoundRobin returns a Balancer that selects addresses round-robin. It uses r to watch
// the name resolution updates and updates the addresses available correspondingly. // the name resolution updates and updates the addresses available correspondingly.
// //
// Deprecated: please use package balancer/roundrobin. // Deprecated: please use package balancer/roundrobin. May be removed in a future 1.x release.
func RoundRobin(r naming.Resolver) Balancer { func RoundRobin(r naming.Resolver) Balancer {
return &roundRobin{r: r} return &roundRobin{r: r}
} }

View file

@ -73,7 +73,9 @@ func (b *baseBalancer) HandleResolvedAddrs(addrs []resolver.Address, err error)
func (b *baseBalancer) UpdateClientConnState(s balancer.ClientConnState) { func (b *baseBalancer) UpdateClientConnState(s balancer.ClientConnState) {
// TODO: handle s.ResolverState.Err (log if not nil) once implemented. // TODO: handle s.ResolverState.Err (log if not nil) once implemented.
// TODO: handle s.ResolverState.ServiceConfig? // TODO: handle s.ResolverState.ServiceConfig?
grpclog.Infoln("base.baseBalancer: got new ClientConn state: ", s) if grpclog.V(2) {
grpclog.Infoln("base.baseBalancer: got new ClientConn state: ", s)
}
// addrsSet is the set converted from addrs, it's used for quick lookup of an address. // addrsSet is the set converted from addrs, it's used for quick lookup of an address.
addrsSet := make(map[resolver.Address]struct{}) addrsSet := make(map[resolver.Address]struct{})
for _, a := range s.ResolverState.Addresses { for _, a := range s.ResolverState.Addresses {
@ -127,10 +129,14 @@ func (b *baseBalancer) HandleSubConnStateChange(sc balancer.SubConn, s connectiv
func (b *baseBalancer) UpdateSubConnState(sc balancer.SubConn, state balancer.SubConnState) { func (b *baseBalancer) UpdateSubConnState(sc balancer.SubConn, state balancer.SubConnState) {
s := state.ConnectivityState s := state.ConnectivityState
grpclog.Infof("base.baseBalancer: handle SubConn state change: %p, %v", sc, s) if grpclog.V(2) {
grpclog.Infof("base.baseBalancer: handle SubConn state change: %p, %v", sc, s)
}
oldS, ok := b.scStates[sc] oldS, ok := b.scStates[sc]
if !ok { if !ok {
grpclog.Infof("base.baseBalancer: got state changes for an unknown SubConn: %p, %v", sc, s) if grpclog.V(2) {
grpclog.Infof("base.baseBalancer: got state changes for an unknown SubConn: %p, %v", sc, s)
}
return return
} }
b.scStates[sc] = s b.scStates[sc] = s

View file

@ -183,7 +183,7 @@ func (ccb *ccBalancerWrapper) handleSubConnStateChange(sc balancer.SubConn, s co
func (ccb *ccBalancerWrapper) updateClientConnState(ccs *balancer.ClientConnState) { func (ccb *ccBalancerWrapper) updateClientConnState(ccs *balancer.ClientConnState) {
if ccb.cc.curBalancerName != grpclbName { if ccb.cc.curBalancerName != grpclbName {
// Filter any grpclb addresses since we don't have the grpclb balancer. // Filter any grpclb addresses since we don't have the grpclb balancer.
s := ccs.ResolverState s := &ccs.ResolverState
for i := 0; i < len(s.Addresses); { for i := 0; i < len(s.Addresses); {
if s.Addresses[i].Type == resolver.GRPCLB { if s.Addresses[i].Type == resolver.GRPCLB {
copy(s.Addresses[i:], s.Addresses[i+1:]) copy(s.Addresses[i:], s.Addresses[i+1:])

View file

@ -38,7 +38,6 @@ import (
"google.golang.org/grpc/grpclog" "google.golang.org/grpc/grpclog"
"google.golang.org/grpc/internal/backoff" "google.golang.org/grpc/internal/backoff"
"google.golang.org/grpc/internal/channelz" "google.golang.org/grpc/internal/channelz"
"google.golang.org/grpc/internal/envconfig"
"google.golang.org/grpc/internal/grpcsync" "google.golang.org/grpc/internal/grpcsync"
"google.golang.org/grpc/internal/transport" "google.golang.org/grpc/internal/transport"
"google.golang.org/grpc/keepalive" "google.golang.org/grpc/keepalive"
@ -1061,8 +1060,8 @@ func (ac *addrConn) resetTransport() {
ac.mu.Lock() ac.mu.Lock()
if ac.state == connectivity.Shutdown { if ac.state == connectivity.Shutdown {
newTr.Close()
ac.mu.Unlock() ac.mu.Unlock()
newTr.Close()
return return
} }
ac.curAddr = addr ac.curAddr = addr
@ -1077,20 +1076,16 @@ func (ac *addrConn) resetTransport() {
// we restart from the top of the addr list. // we restart from the top of the addr list.
<-reconnect.Done() <-reconnect.Done()
hcancel() hcancel()
// restart connecting - the top of the loop will set state to
// Need to reconnect after a READY, the addrConn enters // CONNECTING. This is against the current connectivity semantics doc,
// TRANSIENT_FAILURE. // however it allows for graceful behavior for RPCs not yet dispatched
// - unfortunate timing would otherwise lead to the RPC failing even
// though the TRANSIENT_FAILURE state (called for by the doc) would be
// instantaneous.
// //
// This will set addrConn to TRANSIENT_FAILURE for a very short period // Ideally we should transition to Idle here and block until there is
// of time, and turns CONNECTING. It seems reasonable to skip this, but // RPC activity that leads to the balancer requesting a reconnect of
// READY-CONNECTING is not a valid transition. // the associated SubConn.
ac.mu.Lock()
if ac.state == connectivity.Shutdown {
ac.mu.Unlock()
return
}
ac.updateConnectivityState(connectivity.TransientFailure)
ac.mu.Unlock()
} }
} }
@ -1147,14 +1142,35 @@ func (ac *addrConn) createTransport(addr resolver.Address, copts transport.Conne
Authority: ac.cc.authority, Authority: ac.cc.authority,
} }
once := sync.Once{}
onGoAway := func(r transport.GoAwayReason) { onGoAway := func(r transport.GoAwayReason) {
ac.mu.Lock() ac.mu.Lock()
ac.adjustParams(r) ac.adjustParams(r)
once.Do(func() {
if ac.state == connectivity.Ready {
// Prevent this SubConn from being used for new RPCs by setting its
// state to Connecting.
//
// TODO: this should be Idle when grpc-go properly supports it.
ac.updateConnectivityState(connectivity.Connecting)
}
})
ac.mu.Unlock() ac.mu.Unlock()
reconnect.Fire() reconnect.Fire()
} }
onClose := func() { onClose := func() {
ac.mu.Lock()
once.Do(func() {
if ac.state == connectivity.Ready {
// Prevent this SubConn from being used for new RPCs by setting its
// state to Connecting.
//
// TODO: this should be Idle when grpc-go properly supports it.
ac.updateConnectivityState(connectivity.Connecting)
}
})
ac.mu.Unlock()
close(onCloseCalled) close(onCloseCalled)
reconnect.Fire() reconnect.Fire()
} }
@ -1176,20 +1192,18 @@ func (ac *addrConn) createTransport(addr resolver.Address, copts transport.Conne
return nil, nil, err return nil, nil, err
} }
if ac.dopts.reqHandshake == envconfig.RequireHandshakeOn { select {
select { case <-time.After(connectDeadline.Sub(time.Now())):
case <-time.After(connectDeadline.Sub(time.Now())): // We didn't get the preface in time.
// We didn't get the preface in time. newTr.Close()
newTr.Close() grpclog.Warningf("grpc: addrConn.createTransport failed to connect to %v: didn't receive server preface in time. Reconnecting...", addr)
grpclog.Warningf("grpc: addrConn.createTransport failed to connect to %v: didn't receive server preface in time. Reconnecting...", addr) return nil, nil, errors.New("timed out waiting for server handshake")
return nil, nil, errors.New("timed out waiting for server handshake") case <-prefaceReceived:
case <-prefaceReceived: // We got the preface - huzzah! things are good.
// We got the preface - huzzah! things are good. case <-onCloseCalled:
case <-onCloseCalled: // The transport has already closed - noop.
// The transport has already closed - noop. return nil, nil, errors.New("connection closed")
return nil, nil, errors.New("connection closed") // TODO(deklerk) this should bail on ac.ctx.Done(). Add a test and fix.
// TODO(deklerk) this should bail on ac.ctx.Done(). Add a test and fix.
}
} }
return newTr, reconnect, nil return newTr, reconnect, nil
} }

View file

@ -60,7 +60,6 @@ type dialOptions struct {
balancerBuilder balancer.Builder balancerBuilder balancer.Builder
// This is to support grpclb. // This is to support grpclb.
resolverBuilder resolver.Builder resolverBuilder resolver.Builder
reqHandshake envconfig.RequireHandshakeSetting
channelzParentID int64 channelzParentID int64
disableServiceConfig bool disableServiceConfig bool
disableRetry bool disableRetry bool
@ -100,17 +99,6 @@ func newFuncDialOption(f func(*dialOptions)) *funcDialOption {
} }
} }
// WithWaitForHandshake blocks until the initial settings frame is received from
// the server before assigning RPCs to the connection.
//
// Deprecated: this is the default behavior, and this option will be removed
// after the 1.18 release.
func WithWaitForHandshake() DialOption {
return newFuncDialOption(func(o *dialOptions) {
o.reqHandshake = envconfig.RequireHandshakeOn
})
}
// WithWriteBufferSize determines how much data can be batched before doing a // WithWriteBufferSize determines how much data can be batched before doing a
// write on the wire. The corresponding memory allocation for this buffer will // write on the wire. The corresponding memory allocation for this buffer will
// be twice the size to keep syscalls low. The default value for this buffer is // be twice the size to keep syscalls low. The default value for this buffer is
@ -156,7 +144,8 @@ func WithInitialConnWindowSize(s int32) DialOption {
// WithMaxMsgSize returns a DialOption which sets the maximum message size the // WithMaxMsgSize returns a DialOption which sets the maximum message size the
// client can receive. // client can receive.
// //
// Deprecated: use WithDefaultCallOptions(MaxCallRecvMsgSize(s)) instead. // Deprecated: use WithDefaultCallOptions(MaxCallRecvMsgSize(s)) instead. Will
// be supported throughout 1.x.
func WithMaxMsgSize(s int) DialOption { func WithMaxMsgSize(s int) DialOption {
return WithDefaultCallOptions(MaxCallRecvMsgSize(s)) return WithDefaultCallOptions(MaxCallRecvMsgSize(s))
} }
@ -172,7 +161,8 @@ func WithDefaultCallOptions(cos ...CallOption) DialOption {
// WithCodec returns a DialOption which sets a codec for message marshaling and // WithCodec returns a DialOption which sets a codec for message marshaling and
// unmarshaling. // unmarshaling.
// //
// Deprecated: use WithDefaultCallOptions(ForceCodec(_)) instead. // Deprecated: use WithDefaultCallOptions(ForceCodec(_)) instead. Will be
// supported throughout 1.x.
func WithCodec(c Codec) DialOption { func WithCodec(c Codec) DialOption {
return WithDefaultCallOptions(CallCustomCodec(c)) return WithDefaultCallOptions(CallCustomCodec(c))
} }
@ -181,7 +171,7 @@ func WithCodec(c Codec) DialOption {
// message compression. It has lower priority than the compressor set by the // message compression. It has lower priority than the compressor set by the
// UseCompressor CallOption. // UseCompressor CallOption.
// //
// Deprecated: use UseCompressor instead. // Deprecated: use UseCompressor instead. Will be supported throughout 1.x.
func WithCompressor(cp Compressor) DialOption { func WithCompressor(cp Compressor) DialOption {
return newFuncDialOption(func(o *dialOptions) { return newFuncDialOption(func(o *dialOptions) {
o.cp = cp o.cp = cp
@ -196,7 +186,8 @@ func WithCompressor(cp Compressor) DialOption {
// message. If no compressor is registered for the encoding, an Unimplemented // message. If no compressor is registered for the encoding, an Unimplemented
// status error will be returned. // status error will be returned.
// //
// Deprecated: use encoding.RegisterCompressor instead. // Deprecated: use encoding.RegisterCompressor instead. Will be supported
// throughout 1.x.
func WithDecompressor(dc Decompressor) DialOption { func WithDecompressor(dc Decompressor) DialOption {
return newFuncDialOption(func(o *dialOptions) { return newFuncDialOption(func(o *dialOptions) {
o.dc = dc o.dc = dc
@ -207,7 +198,7 @@ func WithDecompressor(dc Decompressor) DialOption {
// Name resolver will be ignored if this DialOption is specified. // Name resolver will be ignored if this DialOption is specified.
// //
// Deprecated: use the new balancer APIs in balancer package and // Deprecated: use the new balancer APIs in balancer package and
// WithBalancerName. // WithBalancerName. Will be removed in a future 1.x release.
func WithBalancer(b Balancer) DialOption { func WithBalancer(b Balancer) DialOption {
return newFuncDialOption(func(o *dialOptions) { return newFuncDialOption(func(o *dialOptions) {
o.balancerBuilder = &balancerWrapperBuilder{ o.balancerBuilder = &balancerWrapperBuilder{
@ -223,7 +214,8 @@ func WithBalancer(b Balancer) DialOption {
// The balancer cannot be overridden by balancer option specified by service // The balancer cannot be overridden by balancer option specified by service
// config. // config.
// //
// This is an EXPERIMENTAL API. // Deprecated: use WithDefaultServiceConfig and WithDisableServiceConfig
// instead. Will be removed in a future 1.x release.
func WithBalancerName(balancerName string) DialOption { func WithBalancerName(balancerName string) DialOption {
builder := balancer.Get(balancerName) builder := balancer.Get(balancerName)
if builder == nil { if builder == nil {
@ -244,9 +236,10 @@ func withResolverBuilder(b resolver.Builder) DialOption {
// WithServiceConfig returns a DialOption which has a channel to read the // WithServiceConfig returns a DialOption which has a channel to read the
// service configuration. // service configuration.
// //
// Deprecated: service config should be received through name resolver, as // Deprecated: service config should be received through name resolver or via
// specified here. // WithDefaultServiceConfig, as specified at
// https://github.com/grpc/grpc/blob/master/doc/service_config.md // https://github.com/grpc/grpc/blob/master/doc/service_config.md. Will be
// removed in a future 1.x release.
func WithServiceConfig(c <-chan ServiceConfig) DialOption { func WithServiceConfig(c <-chan ServiceConfig) DialOption {
return newFuncDialOption(func(o *dialOptions) { return newFuncDialOption(func(o *dialOptions) {
o.scChan = c o.scChan = c
@ -329,7 +322,8 @@ func WithCredentialsBundle(b credentials.Bundle) DialOption {
// WithTimeout returns a DialOption that configures a timeout for dialing a // WithTimeout returns a DialOption that configures a timeout for dialing a
// ClientConn initially. This is valid if and only if WithBlock() is present. // ClientConn initially. This is valid if and only if WithBlock() is present.
// //
// Deprecated: use DialContext and context.WithTimeout instead. // Deprecated: use DialContext and context.WithTimeout instead. Will be
// supported throughout 1.x.
func WithTimeout(d time.Duration) DialOption { func WithTimeout(d time.Duration) DialOption {
return newFuncDialOption(func(o *dialOptions) { return newFuncDialOption(func(o *dialOptions) {
o.timeout = d o.timeout = d
@ -356,7 +350,8 @@ func init() {
// is returned by f, gRPC checks the error's Temporary() method to decide if it // is returned by f, gRPC checks the error's Temporary() method to decide if it
// should try to reconnect to the network address. // should try to reconnect to the network address.
// //
// Deprecated: use WithContextDialer instead // Deprecated: use WithContextDialer instead. Will be supported throughout
// 1.x.
func WithDialer(f func(string, time.Duration) (net.Conn, error)) DialOption { func WithDialer(f func(string, time.Duration) (net.Conn, error)) DialOption {
return WithContextDialer( return WithContextDialer(
func(ctx context.Context, addr string) (net.Conn, error) { func(ctx context.Context, addr string) (net.Conn, error) {
@ -480,8 +475,10 @@ func WithDisableServiceConfig() DialOption {
// WithDefaultServiceConfig returns a DialOption that configures the default // WithDefaultServiceConfig returns a DialOption that configures the default
// service config, which will be used in cases where: // service config, which will be used in cases where:
// 1. WithDisableServiceConfig is called. //
// 2. Resolver does not return service config or if the resolver gets and invalid config. // 1. WithDisableServiceConfig is also used.
// 2. Resolver does not return a service config or if the resolver returns an
// invalid service config.
// //
// This API is EXPERIMENTAL. // This API is EXPERIMENTAL.
func WithDefaultServiceConfig(s string) DialOption { func WithDefaultServiceConfig(s string) DialOption {
@ -537,7 +534,6 @@ func withHealthCheckFunc(f internal.HealthChecker) DialOption {
func defaultDialOptions() dialOptions { func defaultDialOptions() dialOptions {
return dialOptions{ return dialOptions{
disableRetry: !envconfig.Retry, disableRetry: !envconfig.Retry,
reqHandshake: envconfig.RequireHandshake,
healthCheckFunc: internal.HealthCheckFunc, healthCheckFunc: internal.HealthCheckFunc,
copts: transport.ConnectOptions{ copts: transport.ConnectOptions{
WriteBufferSize: defaultWriteBufSize, WriteBufferSize: defaultWriteBufSize,

View file

@ -25,40 +25,11 @@ import (
) )
const ( const (
prefix = "GRPC_GO_" prefix = "GRPC_GO_"
retryStr = prefix + "RETRY" retryStr = prefix + "RETRY"
requireHandshakeStr = prefix + "REQUIRE_HANDSHAKE"
)
// RequireHandshakeSetting describes the settings for handshaking.
type RequireHandshakeSetting int
const (
// RequireHandshakeOn indicates to wait for handshake before considering a
// connection ready/successful.
RequireHandshakeOn RequireHandshakeSetting = iota
// RequireHandshakeOff indicates to not wait for handshake before
// considering a connection ready/successful.
RequireHandshakeOff
) )
var ( var (
// Retry is set if retry is explicitly enabled via "GRPC_GO_RETRY=on". // Retry is set if retry is explicitly enabled via "GRPC_GO_RETRY=on".
Retry = strings.EqualFold(os.Getenv(retryStr), "on") Retry = strings.EqualFold(os.Getenv(retryStr), "on")
// RequireHandshake is set based upon the GRPC_GO_REQUIRE_HANDSHAKE
// environment variable.
//
// Will be removed after the 1.18 release.
RequireHandshake = RequireHandshakeOn
) )
func init() {
switch strings.ToLower(os.Getenv(requireHandshakeStr)) {
case "on":
fallthrough
default:
RequireHandshake = RequireHandshakeOn
case "off":
RequireHandshake = RequireHandshakeOff
}
}

View file

@ -23,6 +23,7 @@ import (
"fmt" "fmt"
"runtime" "runtime"
"sync" "sync"
"sync/atomic"
"golang.org/x/net/http2" "golang.org/x/net/http2"
"golang.org/x/net/http2/hpack" "golang.org/x/net/http2/hpack"
@ -84,12 +85,24 @@ func (il *itemList) isEmpty() bool {
// the control buffer of transport. They represent different aspects of // the control buffer of transport. They represent different aspects of
// control tasks, e.g., flow control, settings, streaming resetting, etc. // control tasks, e.g., flow control, settings, streaming resetting, etc.
// maxQueuedTransportResponseFrames is the most queued "transport response"
// frames we will buffer before preventing new reads from occurring on the
// transport. These are control frames sent in response to client requests,
// such as RST_STREAM due to bad headers or settings acks.
const maxQueuedTransportResponseFrames = 50
type cbItem interface {
isTransportResponseFrame() bool
}
// registerStream is used to register an incoming stream with loopy writer. // registerStream is used to register an incoming stream with loopy writer.
type registerStream struct { type registerStream struct {
streamID uint32 streamID uint32
wq *writeQuota wq *writeQuota
} }
func (*registerStream) isTransportResponseFrame() bool { return false }
// headerFrame is also used to register stream on the client-side. // headerFrame is also used to register stream on the client-side.
type headerFrame struct { type headerFrame struct {
streamID uint32 streamID uint32
@ -102,6 +115,10 @@ type headerFrame struct {
onOrphaned func(error) // Valid on client-side onOrphaned func(error) // Valid on client-side
} }
func (h *headerFrame) isTransportResponseFrame() bool {
return h.cleanup != nil && h.cleanup.rst // Results in a RST_STREAM
}
type cleanupStream struct { type cleanupStream struct {
streamID uint32 streamID uint32
rst bool rst bool
@ -109,6 +126,8 @@ type cleanupStream struct {
onWrite func() onWrite func()
} }
func (c *cleanupStream) isTransportResponseFrame() bool { return c.rst } // Results in a RST_STREAM
type dataFrame struct { type dataFrame struct {
streamID uint32 streamID uint32
endStream bool endStream bool
@ -119,27 +138,41 @@ type dataFrame struct {
onEachWrite func() onEachWrite func()
} }
func (*dataFrame) isTransportResponseFrame() bool { return false }
type incomingWindowUpdate struct { type incomingWindowUpdate struct {
streamID uint32 streamID uint32
increment uint32 increment uint32
} }
func (*incomingWindowUpdate) isTransportResponseFrame() bool { return false }
type outgoingWindowUpdate struct { type outgoingWindowUpdate struct {
streamID uint32 streamID uint32
increment uint32 increment uint32
} }
func (*outgoingWindowUpdate) isTransportResponseFrame() bool {
return false // window updates are throttled by thresholds
}
type incomingSettings struct { type incomingSettings struct {
ss []http2.Setting ss []http2.Setting
} }
func (*incomingSettings) isTransportResponseFrame() bool { return true } // Results in a settings ACK
type outgoingSettings struct { type outgoingSettings struct {
ss []http2.Setting ss []http2.Setting
} }
func (*outgoingSettings) isTransportResponseFrame() bool { return false }
type incomingGoAway struct { type incomingGoAway struct {
} }
func (*incomingGoAway) isTransportResponseFrame() bool { return false }
type goAway struct { type goAway struct {
code http2.ErrCode code http2.ErrCode
debugData []byte debugData []byte
@ -147,15 +180,21 @@ type goAway struct {
closeConn bool closeConn bool
} }
func (*goAway) isTransportResponseFrame() bool { return false }
type ping struct { type ping struct {
ack bool ack bool
data [8]byte data [8]byte
} }
func (*ping) isTransportResponseFrame() bool { return true }
type outFlowControlSizeRequest struct { type outFlowControlSizeRequest struct {
resp chan uint32 resp chan uint32
} }
func (*outFlowControlSizeRequest) isTransportResponseFrame() bool { return false }
type outStreamState int type outStreamState int
const ( const (
@ -238,6 +277,14 @@ type controlBuffer struct {
consumerWaiting bool consumerWaiting bool
list *itemList list *itemList
err error err error
// transportResponseFrames counts the number of queued items that represent
// the response of an action initiated by the peer. trfChan is created
// when transportResponseFrames >= maxQueuedTransportResponseFrames and is
// closed and nilled when transportResponseFrames drops below the
// threshold. Both fields are protected by mu.
transportResponseFrames int
trfChan atomic.Value // *chan struct{}
} }
func newControlBuffer(done <-chan struct{}) *controlBuffer { func newControlBuffer(done <-chan struct{}) *controlBuffer {
@ -248,12 +295,24 @@ func newControlBuffer(done <-chan struct{}) *controlBuffer {
} }
} }
func (c *controlBuffer) put(it interface{}) error { // throttle blocks if there are too many incomingSettings/cleanupStreams in the
// controlbuf.
func (c *controlBuffer) throttle() {
ch, _ := c.trfChan.Load().(*chan struct{})
if ch != nil {
select {
case <-*ch:
case <-c.done:
}
}
}
func (c *controlBuffer) put(it cbItem) error {
_, err := c.executeAndPut(nil, it) _, err := c.executeAndPut(nil, it)
return err return err
} }
func (c *controlBuffer) executeAndPut(f func(it interface{}) bool, it interface{}) (bool, error) { func (c *controlBuffer) executeAndPut(f func(it interface{}) bool, it cbItem) (bool, error) {
var wakeUp bool var wakeUp bool
c.mu.Lock() c.mu.Lock()
if c.err != nil { if c.err != nil {
@ -271,6 +330,15 @@ func (c *controlBuffer) executeAndPut(f func(it interface{}) bool, it interface{
c.consumerWaiting = false c.consumerWaiting = false
} }
c.list.enqueue(it) c.list.enqueue(it)
if it.isTransportResponseFrame() {
c.transportResponseFrames++
if c.transportResponseFrames == maxQueuedTransportResponseFrames {
// We are adding the frame that puts us over the threshold; create
// a throttling channel.
ch := make(chan struct{})
c.trfChan.Store(&ch)
}
}
c.mu.Unlock() c.mu.Unlock()
if wakeUp { if wakeUp {
select { select {
@ -304,7 +372,17 @@ func (c *controlBuffer) get(block bool) (interface{}, error) {
return nil, c.err return nil, c.err
} }
if !c.list.isEmpty() { if !c.list.isEmpty() {
h := c.list.dequeue() h := c.list.dequeue().(cbItem)
if h.isTransportResponseFrame() {
if c.transportResponseFrames == maxQueuedTransportResponseFrames {
// We are removing the frame that put us over the
// threshold; close and clear the throttling channel.
ch := c.trfChan.Load().(*chan struct{})
close(*ch)
c.trfChan.Store((*chan struct{})(nil))
}
c.transportResponseFrames--
}
c.mu.Unlock() c.mu.Unlock()
return h, nil return h, nil
} }

View file

@ -149,6 +149,7 @@ func (f *inFlow) maybeAdjust(n uint32) uint32 {
n = uint32(math.MaxInt32) n = uint32(math.MaxInt32)
} }
f.mu.Lock() f.mu.Lock()
defer f.mu.Unlock()
// estSenderQuota is the receiver's view of the maximum number of bytes the sender // estSenderQuota is the receiver's view of the maximum number of bytes the sender
// can send without a window update. // can send without a window update.
estSenderQuota := int32(f.limit - (f.pendingData + f.pendingUpdate)) estSenderQuota := int32(f.limit - (f.pendingData + f.pendingUpdate))
@ -169,10 +170,8 @@ func (f *inFlow) maybeAdjust(n uint32) uint32 {
// is padded; We will fallback on the current available window(at least a 1/4th of the limit). // is padded; We will fallback on the current available window(at least a 1/4th of the limit).
f.delta = n f.delta = n
} }
f.mu.Unlock()
return f.delta return f.delta
} }
f.mu.Unlock()
return 0 return 0
} }

View file

@ -493,6 +493,9 @@ func (t *http2Client) createAudience(callHdr *CallHdr) string {
} }
func (t *http2Client) getTrAuthData(ctx context.Context, audience string) (map[string]string, error) { func (t *http2Client) getTrAuthData(ctx context.Context, audience string) (map[string]string, error) {
if len(t.perRPCCreds) == 0 {
return nil, nil
}
authData := map[string]string{} authData := map[string]string{}
for _, c := range t.perRPCCreds { for _, c := range t.perRPCCreds {
data, err := c.GetRequestMetadata(ctx, audience) data, err := c.GetRequestMetadata(ctx, audience)
@ -513,7 +516,7 @@ func (t *http2Client) getTrAuthData(ctx context.Context, audience string) (map[s
} }
func (t *http2Client) getCallAuthData(ctx context.Context, audience string, callHdr *CallHdr) (map[string]string, error) { func (t *http2Client) getCallAuthData(ctx context.Context, audience string, callHdr *CallHdr) (map[string]string, error) {
callAuthData := map[string]string{} var callAuthData map[string]string
// Check if credentials.PerRPCCredentials were provided via call options. // Check if credentials.PerRPCCredentials were provided via call options.
// Note: if these credentials are provided both via dial options and call // Note: if these credentials are provided both via dial options and call
// options, then both sets of credentials will be applied. // options, then both sets of credentials will be applied.
@ -525,6 +528,7 @@ func (t *http2Client) getCallAuthData(ctx context.Context, audience string, call
if err != nil { if err != nil {
return nil, status.Errorf(codes.Internal, "transport: %v", err) return nil, status.Errorf(codes.Internal, "transport: %v", err)
} }
callAuthData = make(map[string]string, len(data))
for k, v := range data { for k, v := range data {
// Capital header names are illegal in HTTP/2 // Capital header names are illegal in HTTP/2
k = strings.ToLower(k) k = strings.ToLower(k)
@ -556,7 +560,6 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea
if atomic.CompareAndSwapUint32(&s.headerChanClosed, 0, 1) { if atomic.CompareAndSwapUint32(&s.headerChanClosed, 0, 1) {
close(s.headerChan) close(s.headerChan)
} }
} }
hdr := &headerFrame{ hdr := &headerFrame{
hf: headerFields, hf: headerFields,
@ -769,6 +772,9 @@ func (t *http2Client) Close() error {
t.mu.Unlock() t.mu.Unlock()
return nil return nil
} }
// Call t.onClose before setting the state to closing to prevent the client
// from attempting to create new streams ASAP.
t.onClose()
t.state = closing t.state = closing
streams := t.activeStreams streams := t.activeStreams
t.activeStreams = nil t.activeStreams = nil
@ -789,7 +795,6 @@ func (t *http2Client) Close() error {
} }
t.statsHandler.HandleConn(t.ctx, connEnd) t.statsHandler.HandleConn(t.ctx, connEnd)
} }
t.onClose()
return err return err
} }
@ -978,9 +983,9 @@ func (t *http2Client) handleRSTStream(f *http2.RSTStreamFrame) {
statusCode = codes.Unknown statusCode = codes.Unknown
} }
if statusCode == codes.Canceled { if statusCode == codes.Canceled {
// Our deadline was already exceeded, and that was likely the cause of if d, ok := s.ctx.Deadline(); ok && !d.After(time.Now()) {
// this cancelation. Alter the status code accordingly. // Our deadline was already exceeded, and that was likely the cause
if d, ok := s.ctx.Deadline(); ok && d.After(time.Now()) { // of this cancelation. Alter the status code accordingly.
statusCode = codes.DeadlineExceeded statusCode = codes.DeadlineExceeded
} }
} }
@ -1085,11 +1090,12 @@ func (t *http2Client) handleGoAway(f *http2.GoAwayFrame) {
default: default:
t.setGoAwayReason(f) t.setGoAwayReason(f)
close(t.goAway) close(t.goAway)
t.state = draining
t.controlBuf.put(&incomingGoAway{}) t.controlBuf.put(&incomingGoAway{})
// Notify the clientconn about the GOAWAY before we set the state to
// This has to be a new goroutine because we're still using the current goroutine to read in the transport. // draining, to allow the client to stop attempting to create streams
// before disallowing new streams on this connection.
t.onGoAway(t.goAwayReason) t.onGoAway(t.goAwayReason)
t.state = draining
} }
// All streams with IDs greater than the GoAwayId // All streams with IDs greater than the GoAwayId
// and smaller than the previous GoAway ID should be killed. // and smaller than the previous GoAway ID should be killed.
@ -1239,6 +1245,7 @@ func (t *http2Client) reader() {
// loop to keep reading incoming messages on this transport. // loop to keep reading incoming messages on this transport.
for { for {
t.controlBuf.throttle()
frame, err := t.framer.fr.ReadFrame() frame, err := t.framer.fr.ReadFrame()
if t.keepaliveEnabled { if t.keepaliveEnabled {
atomic.CompareAndSwapUint32(&t.activity, 0, 1) atomic.CompareAndSwapUint32(&t.activity, 0, 1)
@ -1326,6 +1333,7 @@ func (t *http2Client) keepalive() {
timer.Reset(t.kp.Time) timer.Reset(t.kp.Time)
continue continue
} }
infof("transport: closing client transport due to idleness.")
t.Close() t.Close()
return return
case <-t.ctx.Done(): case <-t.ctx.Done():

View file

@ -436,6 +436,7 @@ func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(
func (t *http2Server) HandleStreams(handle func(*Stream), traceCtx func(context.Context, string) context.Context) { func (t *http2Server) HandleStreams(handle func(*Stream), traceCtx func(context.Context, string) context.Context) {
defer close(t.readerDone) defer close(t.readerDone)
for { for {
t.controlBuf.throttle()
frame, err := t.framer.fr.ReadFrame() frame, err := t.framer.fr.ReadFrame()
atomic.StoreUint32(&t.activity, 1) atomic.StoreUint32(&t.activity, 1)
if err != nil { if err != nil {
@ -766,6 +767,10 @@ func (t *http2Server) WriteHeader(s *Stream, md metadata.MD) error {
return nil return nil
} }
func (t *http2Server) setResetPingStrikes() {
atomic.StoreUint32(&t.resetPingStrikes, 1)
}
func (t *http2Server) writeHeaderLocked(s *Stream) error { func (t *http2Server) writeHeaderLocked(s *Stream) error {
// TODO(mmukhi): Benchmark if the performance gets better if count the metadata and other header fields // TODO(mmukhi): Benchmark if the performance gets better if count the metadata and other header fields
// first and create a slice of that exact size. // first and create a slice of that exact size.
@ -780,9 +785,7 @@ func (t *http2Server) writeHeaderLocked(s *Stream) error {
streamID: s.id, streamID: s.id,
hf: headerFields, hf: headerFields,
endStream: false, endStream: false,
onWrite: func() { onWrite: t.setResetPingStrikes,
atomic.StoreUint32(&t.resetPingStrikes, 1)
},
}) })
if !success { if !success {
if err != nil { if err != nil {
@ -842,9 +845,7 @@ func (t *http2Server) WriteStatus(s *Stream, st *status.Status) error {
streamID: s.id, streamID: s.id,
hf: headerFields, hf: headerFields,
endStream: true, endStream: true,
onWrite: func() { onWrite: t.setResetPingStrikes,
atomic.StoreUint32(&t.resetPingStrikes, 1)
},
} }
s.hdrMu.Unlock() s.hdrMu.Unlock()
success, err := t.controlBuf.execute(t.checkForHeaderListSize, trailingHeader) success, err := t.controlBuf.execute(t.checkForHeaderListSize, trailingHeader)
@ -896,12 +897,10 @@ func (t *http2Server) Write(s *Stream, hdr []byte, data []byte, opts *Options) e
hdr = append(hdr, data[:emptyLen]...) hdr = append(hdr, data[:emptyLen]...)
data = data[emptyLen:] data = data[emptyLen:]
df := &dataFrame{ df := &dataFrame{
streamID: s.id, streamID: s.id,
h: hdr, h: hdr,
d: data, d: data,
onEachWrite: func() { onEachWrite: t.setResetPingStrikes,
atomic.StoreUint32(&t.resetPingStrikes, 1)
},
} }
if err := s.wq.get(int32(len(hdr) + len(data))); err != nil { if err := s.wq.get(int32(len(hdr) + len(data))); err != nil {
select { select {
@ -967,6 +966,7 @@ func (t *http2Server) keepalive() {
select { select {
case <-maxAge.C: case <-maxAge.C:
// Close the connection after grace period. // Close the connection after grace period.
infof("transport: closing server transport due to maximum connection age.")
t.Close() t.Close()
// Resetting the timer so that the clean-up doesn't deadlock. // Resetting the timer so that the clean-up doesn't deadlock.
maxAge.Reset(infinity) maxAge.Reset(infinity)
@ -980,6 +980,7 @@ func (t *http2Server) keepalive() {
continue continue
} }
if pingSent { if pingSent {
infof("transport: closing server transport due to idleness.")
t.Close() t.Close()
// Resetting the timer so that the clean-up doesn't deadlock. // Resetting the timer so that the clean-up doesn't deadlock.
keepalive.Reset(infinity) keepalive.Reset(infinity)

View file

@ -184,6 +184,19 @@ func (r *recvBufferReader) readClient(p []byte) (n int, err error) {
// r.readAdditional acts on that message and returns the necessary error. // r.readAdditional acts on that message and returns the necessary error.
select { select {
case <-r.ctxDone: case <-r.ctxDone:
// Note that this adds the ctx error to the end of recv buffer, and
// reads from the head. This will delay the error until recv buffer is
// empty, thus will delay ctx cancellation in Recv().
//
// It's done this way to fix a race between ctx cancel and trailer. The
// race was, stream.Recv() may return ctx error if ctxDone wins the
// race, but stream.Trailer() may return a non-nil md because the stream
// was not marked as done when trailer is received. This closeStream
// call will mark stream as done, thus fix the race.
//
// TODO: delaying ctx error seems like a unnecessary side effect. What
// we really want is to mark the stream as done, and return ctx error
// faster.
r.closeStream(ContextErr(r.ctx.Err())) r.closeStream(ContextErr(r.ctx.Err()))
m := <-r.recv.get() m := <-r.recv.get()
return r.readAdditional(m, p) return r.readAdditional(m, p)
@ -298,6 +311,14 @@ func (s *Stream) waitOnHeader() error {
} }
select { select {
case <-s.ctx.Done(): case <-s.ctx.Done():
// We prefer success over failure when reading messages because we delay
// context error in stream.Read(). To keep behavior consistent, we also
// prefer success here.
select {
case <-s.headerChan:
return nil
default:
}
return ContextErr(s.ctx.Err()) return ContextErr(s.ctx.Err())
case <-s.headerChan: case <-s.headerChan:
return nil return nil

View file

@ -51,14 +51,18 @@ type pickfirstBalancer struct {
func (b *pickfirstBalancer) HandleResolvedAddrs(addrs []resolver.Address, err error) { func (b *pickfirstBalancer) HandleResolvedAddrs(addrs []resolver.Address, err error) {
if err != nil { if err != nil {
grpclog.Infof("pickfirstBalancer: HandleResolvedAddrs called with error %v", err) if grpclog.V(2) {
grpclog.Infof("pickfirstBalancer: HandleResolvedAddrs called with error %v", err)
}
return return
} }
if b.sc == nil { if b.sc == nil {
b.sc, err = b.cc.NewSubConn(addrs, balancer.NewSubConnOptions{}) b.sc, err = b.cc.NewSubConn(addrs, balancer.NewSubConnOptions{})
if err != nil { if err != nil {
//TODO(yuxuanli): why not change the cc state to Idle? //TODO(yuxuanli): why not change the cc state to Idle?
grpclog.Errorf("pickfirstBalancer: failed to NewSubConn: %v", err) if grpclog.V(2) {
grpclog.Errorf("pickfirstBalancer: failed to NewSubConn: %v", err)
}
return return
} }
b.cc.UpdateBalancerState(connectivity.Idle, &picker{sc: b.sc}) b.cc.UpdateBalancerState(connectivity.Idle, &picker{sc: b.sc})
@ -70,9 +74,13 @@ func (b *pickfirstBalancer) HandleResolvedAddrs(addrs []resolver.Address, err er
} }
func (b *pickfirstBalancer) HandleSubConnStateChange(sc balancer.SubConn, s connectivity.State) { func (b *pickfirstBalancer) HandleSubConnStateChange(sc balancer.SubConn, s connectivity.State) {
grpclog.Infof("pickfirstBalancer: HandleSubConnStateChange: %p, %v", sc, s) if grpclog.V(2) {
grpclog.Infof("pickfirstBalancer: HandleSubConnStateChange: %p, %v", sc, s)
}
if b.sc != sc { if b.sc != sc {
grpclog.Infof("pickfirstBalancer: ignored state change because sc is not recognized") if grpclog.V(2) {
grpclog.Infof("pickfirstBalancer: ignored state change because sc is not recognized")
}
return return
} }
if s == connectivity.Shutdown { if s == connectivity.Shutdown {

View file

@ -42,6 +42,7 @@ import (
"google.golang.org/grpc/grpclog" "google.golang.org/grpc/grpclog"
"google.golang.org/grpc/internal/binarylog" "google.golang.org/grpc/internal/binarylog"
"google.golang.org/grpc/internal/channelz" "google.golang.org/grpc/internal/channelz"
"google.golang.org/grpc/internal/grpcsync"
"google.golang.org/grpc/internal/transport" "google.golang.org/grpc/internal/transport"
"google.golang.org/grpc/keepalive" "google.golang.org/grpc/keepalive"
"google.golang.org/grpc/metadata" "google.golang.org/grpc/metadata"
@ -56,6 +57,8 @@ const (
defaultServerMaxSendMessageSize = math.MaxInt32 defaultServerMaxSendMessageSize = math.MaxInt32
) )
var statusOK = status.New(codes.OK, "")
type methodHandler func(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor UnaryServerInterceptor) (interface{}, error) type methodHandler func(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor UnaryServerInterceptor) (interface{}, error)
// MethodDesc represents an RPC service's method specification. // MethodDesc represents an RPC service's method specification.
@ -97,10 +100,8 @@ type Server struct {
m map[string]*service // service name -> service info m map[string]*service // service name -> service info
events trace.EventLog events trace.EventLog
quit chan struct{} quit *grpcsync.Event
done chan struct{} done *grpcsync.Event
quitOnce sync.Once
doneOnce sync.Once
channelzRemoveOnce sync.Once channelzRemoveOnce sync.Once
serveWG sync.WaitGroup // counts active Serve goroutines for GracefulStop serveWG sync.WaitGroup // counts active Serve goroutines for GracefulStop
@ -388,8 +389,8 @@ func NewServer(opt ...ServerOption) *Server {
opts: opts, opts: opts,
conns: make(map[transport.ServerTransport]bool), conns: make(map[transport.ServerTransport]bool),
m: make(map[string]*service), m: make(map[string]*service),
quit: make(chan struct{}), quit: grpcsync.NewEvent(),
done: make(chan struct{}), done: grpcsync.NewEvent(),
czData: new(channelzData), czData: new(channelzData),
} }
s.cv = sync.NewCond(&s.mu) s.cv = sync.NewCond(&s.mu)
@ -556,11 +557,9 @@ func (s *Server) Serve(lis net.Listener) error {
s.serveWG.Add(1) s.serveWG.Add(1)
defer func() { defer func() {
s.serveWG.Done() s.serveWG.Done()
select { if s.quit.HasFired() {
// Stop or GracefulStop called; block until done and return nil. // Stop or GracefulStop called; block until done and return nil.
case <-s.quit: <-s.done.Done()
<-s.done
default:
} }
}() }()
@ -603,7 +602,7 @@ func (s *Server) Serve(lis net.Listener) error {
timer := time.NewTimer(tempDelay) timer := time.NewTimer(tempDelay)
select { select {
case <-timer.C: case <-timer.C:
case <-s.quit: case <-s.quit.Done():
timer.Stop() timer.Stop()
return nil return nil
} }
@ -613,10 +612,8 @@ func (s *Server) Serve(lis net.Listener) error {
s.printf("done serving; Accept = %v", err) s.printf("done serving; Accept = %v", err)
s.mu.Unlock() s.mu.Unlock()
select { if s.quit.HasFired() {
case <-s.quit:
return nil return nil
default:
} }
return err return err
} }
@ -637,6 +634,10 @@ func (s *Server) Serve(lis net.Listener) error {
// handleRawConn forks a goroutine to handle a just-accepted connection that // handleRawConn forks a goroutine to handle a just-accepted connection that
// has not had any I/O performed on it yet. // has not had any I/O performed on it yet.
func (s *Server) handleRawConn(rawConn net.Conn) { func (s *Server) handleRawConn(rawConn net.Conn) {
if s.quit.HasFired() {
rawConn.Close()
return
}
rawConn.SetDeadline(time.Now().Add(s.opts.connectionTimeout)) rawConn.SetDeadline(time.Now().Add(s.opts.connectionTimeout))
conn, authInfo, err := s.useTransportAuthenticator(rawConn) conn, authInfo, err := s.useTransportAuthenticator(rawConn)
if err != nil { if err != nil {
@ -653,14 +654,6 @@ func (s *Server) handleRawConn(rawConn net.Conn) {
return return
} }
s.mu.Lock()
if s.conns == nil {
s.mu.Unlock()
conn.Close()
return
}
s.mu.Unlock()
// Finish handshaking (HTTP2) // Finish handshaking (HTTP2)
st := s.newHTTP2Transport(conn, authInfo) st := s.newHTTP2Transport(conn, authInfo)
if st == nil { if st == nil {
@ -768,6 +761,9 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// traceInfo returns a traceInfo and associates it with stream, if tracing is enabled. // traceInfo returns a traceInfo and associates it with stream, if tracing is enabled.
// If tracing is not enabled, it returns nil. // If tracing is not enabled, it returns nil.
func (s *Server) traceInfo(st transport.ServerTransport, stream *transport.Stream) (trInfo *traceInfo) { func (s *Server) traceInfo(st transport.ServerTransport, stream *transport.Stream) (trInfo *traceInfo) {
if !EnableTracing {
return nil
}
tr, ok := trace.FromContext(stream.Context()) tr, ok := trace.FromContext(stream.Context())
if !ok { if !ok {
return nil return nil
@ -1078,7 +1074,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
// TODO: Should we be logging if writing status failed here, like above? // TODO: Should we be logging if writing status failed here, like above?
// Should the logging be in WriteStatus? Should we ignore the WriteStatus // Should the logging be in WriteStatus? Should we ignore the WriteStatus
// error or allow the stats handler to see it? // error or allow the stats handler to see it?
err = t.WriteStatus(stream, status.New(codes.OK, "")) err = t.WriteStatus(stream, statusOK)
if binlog != nil { if binlog != nil {
binlog.Log(&binarylog.ServerTrailer{ binlog.Log(&binarylog.ServerTrailer{
Trailer: stream.Trailer(), Trailer: stream.Trailer(),
@ -1236,7 +1232,7 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp
ss.trInfo.tr.LazyLog(stringer("OK"), false) ss.trInfo.tr.LazyLog(stringer("OK"), false)
ss.mu.Unlock() ss.mu.Unlock()
} }
err = t.WriteStatus(ss.s, status.New(codes.OK, "")) err = t.WriteStatus(ss.s, statusOK)
if ss.binlog != nil { if ss.binlog != nil {
ss.binlog.Log(&binarylog.ServerTrailer{ ss.binlog.Log(&binarylog.ServerTrailer{
Trailer: ss.s.Trailer(), Trailer: ss.s.Trailer(),
@ -1353,15 +1349,11 @@ func ServerTransportStreamFromContext(ctx context.Context) ServerTransportStream
// pending RPCs on the client side will get notified by connection // pending RPCs on the client side will get notified by connection
// errors. // errors.
func (s *Server) Stop() { func (s *Server) Stop() {
s.quitOnce.Do(func() { s.quit.Fire()
close(s.quit)
})
defer func() { defer func() {
s.serveWG.Wait() s.serveWG.Wait()
s.doneOnce.Do(func() { s.done.Fire()
close(s.done)
})
}() }()
s.channelzRemoveOnce.Do(func() { s.channelzRemoveOnce.Do(func() {
@ -1398,15 +1390,8 @@ func (s *Server) Stop() {
// accepting new connections and RPCs and blocks until all the pending RPCs are // accepting new connections and RPCs and blocks until all the pending RPCs are
// finished. // finished.
func (s *Server) GracefulStop() { func (s *Server) GracefulStop() {
s.quitOnce.Do(func() { s.quit.Fire()
close(s.quit) defer s.done.Fire()
})
defer func() {
s.doneOnce.Do(func() {
close(s.done)
})
}()
s.channelzRemoveOnce.Do(func() { s.channelzRemoveOnce.Do(func() {
if channelz.IsOn() { if channelz.IsOn() {

View file

@ -58,6 +58,17 @@ func (se *statusError) GRPCStatus() *Status {
return &Status{s: (*spb.Status)(se)} return &Status{s: (*spb.Status)(se)}
} }
// Is implements future error.Is functionality.
// A statusError is equivalent if the code and message are identical.
func (se *statusError) Is(target error) bool {
tse, ok := target.(*statusError)
if !ok {
return false
}
return proto.Equal((*spb.Status)(se), (*spb.Status)(tse))
}
// Status represents an RPC status code, message, and details. It is immutable // Status represents an RPC status code, message, and details. It is immutable
// and should be created with New, Newf, or FromProto. // and should be created with New, Newf, or FromProto.
type Status struct { type Status struct {
@ -132,7 +143,7 @@ func FromProto(s *spb.Status) *Status {
// Status is returned with codes.Unknown and the original error message. // Status is returned with codes.Unknown and the original error message.
func FromError(err error) (s *Status, ok bool) { func FromError(err error) (s *Status, ok bool) {
if err == nil { if err == nil {
return &Status{s: &spb.Status{Code: int32(codes.OK)}}, true return nil, true
} }
if se, ok := err.(interface { if se, ok := err.(interface {
GRPCStatus() *Status GRPCStatus() *Status
@ -206,7 +217,7 @@ func Code(err error) codes.Code {
func FromContextError(err error) *Status { func FromContextError(err error) *Status {
switch err { switch err {
case nil: case nil:
return New(codes.OK, "") return nil
case context.DeadlineExceeded: case context.DeadlineExceeded:
return New(codes.DeadlineExceeded, err.Error()) return New(codes.DeadlineExceeded, err.Error())
case context.Canceled: case context.Canceled:

View file

@ -327,13 +327,23 @@ func newClientStream(ctx context.Context, desc *StreamDesc, cc *ClientConn, meth
return cs, nil return cs, nil
} }
func (cs *clientStream) newAttemptLocked(sh stats.Handler, trInfo *traceInfo) error { // newAttemptLocked creates a new attempt with a transport.
cs.attempt = &csAttempt{ // If it succeeds, then it replaces clientStream's attempt with this new attempt.
func (cs *clientStream) newAttemptLocked(sh stats.Handler, trInfo *traceInfo) (retErr error) {
newAttempt := &csAttempt{
cs: cs, cs: cs,
dc: cs.cc.dopts.dc, dc: cs.cc.dopts.dc,
statsHandler: sh, statsHandler: sh,
trInfo: trInfo, trInfo: trInfo,
} }
defer func() {
if retErr != nil {
// This attempt is not set in the clientStream, so it's finish won't
// be called. Call it here for stats and trace in case they are not
// nil.
newAttempt.finish(retErr)
}
}()
if err := cs.ctx.Err(); err != nil { if err := cs.ctx.Err(); err != nil {
return toRPCErr(err) return toRPCErr(err)
@ -345,8 +355,9 @@ func (cs *clientStream) newAttemptLocked(sh stats.Handler, trInfo *traceInfo) er
if trInfo != nil { if trInfo != nil {
trInfo.firstLine.SetRemoteAddr(t.RemoteAddr()) trInfo.firstLine.SetRemoteAddr(t.RemoteAddr())
} }
cs.attempt.t = t newAttempt.t = t
cs.attempt.done = done newAttempt.done = done
cs.attempt = newAttempt
return nil return nil
} }
@ -395,11 +406,18 @@ type clientStream struct {
serverHeaderBinlogged bool serverHeaderBinlogged bool
mu sync.Mutex mu sync.Mutex
firstAttempt bool // if true, transparent retry is valid firstAttempt bool // if true, transparent retry is valid
numRetries int // exclusive of transparent retry attempt(s) numRetries int // exclusive of transparent retry attempt(s)
numRetriesSincePushback int // retries since pushback; to reset backoff numRetriesSincePushback int // retries since pushback; to reset backoff
finished bool // TODO: replace with atomic cmpxchg or sync.Once? finished bool // TODO: replace with atomic cmpxchg or sync.Once?
attempt *csAttempt // the active client stream attempt // attempt is the active client stream attempt.
// The only place where it is written is the newAttemptLocked method and this method never writes nil.
// So, attempt can be nil only inside newClientStream function when clientStream is first created.
// One of the first things done after clientStream's creation, is to call newAttemptLocked which either
// assigns a non nil value to the attempt or returns an error. If an error is returned from newAttemptLocked,
// then newClientStream calls finish on the clientStream and returns. So, finish method is the only
// place where we need to check if the attempt is nil.
attempt *csAttempt
// TODO(hedging): hedging will have multiple attempts simultaneously. // TODO(hedging): hedging will have multiple attempts simultaneously.
committed bool // active attempt committed for retry? committed bool // active attempt committed for retry?
buffer []func(a *csAttempt) error // operations to replay on retry buffer []func(a *csAttempt) error // operations to replay on retry
@ -457,8 +475,8 @@ func (cs *clientStream) shouldRetry(err error) error {
if cs.attempt.s != nil { if cs.attempt.s != nil {
<-cs.attempt.s.Done() <-cs.attempt.s.Done()
} }
if cs.firstAttempt && !cs.callInfo.failFast && (cs.attempt.s == nil || cs.attempt.s.Unprocessed()) { if cs.firstAttempt && (cs.attempt.s == nil || cs.attempt.s.Unprocessed()) {
// First attempt, wait-for-ready, stream unprocessed: transparently retry. // First attempt, stream unprocessed: transparently retry.
cs.firstAttempt = false cs.firstAttempt = false
return nil return nil
} }
@ -805,11 +823,11 @@ func (cs *clientStream) finish(err error) {
} }
if cs.attempt != nil { if cs.attempt != nil {
cs.attempt.finish(err) cs.attempt.finish(err)
} // after functions all rely upon having a stream.
// after functions all rely upon having a stream. if cs.attempt.s != nil {
if cs.attempt.s != nil { for _, o := range cs.opts {
for _, o := range cs.opts { o.after(cs.callInfo)
o.after(cs.callInfo) }
} }
} }
cs.cancel() cs.cancel()

View file

@ -19,4 +19,4 @@
package grpc package grpc
// Version is the current grpc version. // Version is the current grpc version.
const Version = "1.22.1" const Version = "1.23.0"

11
vendor/google.golang.org/grpc/vet.sh generated vendored
View file

@ -105,12 +105,14 @@ if go help mod >& /dev/null; then
fi fi
# - Collection of static analysis checks # - Collection of static analysis checks
# TODO(menghanl): fix errors in transport_test. # TODO(dfawley): don't use deprecated functions in examples.
staticcheck -go 1.9 -checks 'inherit,-ST1015' -ignore ' staticcheck -go 1.9 -checks 'inherit,-ST1015' -ignore '
google.golang.org/grpc/balancer.go:SA1019 google.golang.org/grpc/balancer.go:SA1019
google.golang.org/grpc/balancer/grpclb/grpclb_remote_balancer.go:SA1019
google.golang.org/grpc/balancer/roundrobin/roundrobin_test.go:SA1019 google.golang.org/grpc/balancer/roundrobin/roundrobin_test.go:SA1019
google.golang.org/grpc/balancer/xds/edsbalancer/balancergroup.go:SA1019 google.golang.org/grpc/xds/internal/balancer/edsbalancer/balancergroup.go:SA1019
google.golang.org/grpc/balancer/xds/xds.go:SA1019 google.golang.org/grpc/xds/internal/balancer/xds.go:SA1019
google.golang.org/grpc/xds/internal/balancer/xds_client.go:SA1019
google.golang.org/grpc/balancer_conn_wrappers.go:SA1019 google.golang.org/grpc/balancer_conn_wrappers.go:SA1019
google.golang.org/grpc/balancer_test.go:SA1019 google.golang.org/grpc/balancer_test.go:SA1019
google.golang.org/grpc/benchmark/benchmain/main.go:SA1019 google.golang.org/grpc/benchmark/benchmain/main.go:SA1019
@ -118,10 +120,13 @@ google.golang.org/grpc/benchmark/worker/benchmark_client.go:SA1019
google.golang.org/grpc/clientconn.go:S1024 google.golang.org/grpc/clientconn.go:S1024
google.golang.org/grpc/clientconn_state_transition_test.go:SA1019 google.golang.org/grpc/clientconn_state_transition_test.go:SA1019
google.golang.org/grpc/clientconn_test.go:SA1019 google.golang.org/grpc/clientconn_test.go:SA1019
google.golang.org/grpc/examples/features/debugging/client/main.go:SA1019
google.golang.org/grpc/examples/features/load_balancing/client/main.go:SA1019
google.golang.org/grpc/internal/transport/handler_server.go:SA1019 google.golang.org/grpc/internal/transport/handler_server.go:SA1019
google.golang.org/grpc/internal/transport/handler_server_test.go:SA1019 google.golang.org/grpc/internal/transport/handler_server_test.go:SA1019
google.golang.org/grpc/resolver/dns/dns_resolver.go:SA1019 google.golang.org/grpc/resolver/dns/dns_resolver.go:SA1019
google.golang.org/grpc/stats/stats_test.go:SA1019 google.golang.org/grpc/stats/stats_test.go:SA1019
google.golang.org/grpc/test/balancer_test.go:SA1019
google.golang.org/grpc/test/channelz_test.go:SA1019 google.golang.org/grpc/test/channelz_test.go:SA1019
google.golang.org/grpc/test/end2end_test.go:SA1019 google.golang.org/grpc/test/end2end_test.go:SA1019
google.golang.org/grpc/test/healthcheck_test.go:SA1019 google.golang.org/grpc/test/healthcheck_test.go:SA1019

10
vendor/modules.txt vendored
View file

@ -102,7 +102,7 @@ golang.org/x/crypto/ed25519/internal/edwards25519
# golang.org/x/lint v0.0.0-20190409202823-959b441ac422 # golang.org/x/lint v0.0.0-20190409202823-959b441ac422
golang.org/x/lint/golint golang.org/x/lint/golint
golang.org/x/lint golang.org/x/lint
# golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 # golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7
golang.org/x/net/context golang.org/x/net/context
golang.org/x/net/http2 golang.org/x/net/http2
golang.org/x/net/trace golang.org/x/net/trace
@ -116,7 +116,7 @@ golang.org/x/oauth2
golang.org/x/oauth2/bitbucket golang.org/x/oauth2/bitbucket
golang.org/x/oauth2/github golang.org/x/oauth2/github
golang.org/x/oauth2/internal golang.org/x/oauth2/internal
# golang.org/x/sys v0.0.0-20190730183949-1393eb018365 # golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a
golang.org/x/sys/windows golang.org/x/sys/windows
golang.org/x/sys/unix golang.org/x/sys/unix
# golang.org/x/text v0.3.2 # golang.org/x/text v0.3.2
@ -124,7 +124,7 @@ golang.org/x/text/secure/bidirule
golang.org/x/text/unicode/bidi golang.org/x/text/unicode/bidi
golang.org/x/text/unicode/norm golang.org/x/text/unicode/norm
golang.org/x/text/transform golang.org/x/text/transform
# golang.org/x/tools v0.0.0-20190730215328-ed3277de2799 # golang.org/x/tools v0.0.0-20190813214729-9dba7caff850
golang.org/x/tools/go/ast/astutil golang.org/x/tools/go/ast/astutil
golang.org/x/tools/go/gcexportdata golang.org/x/tools/go/gcexportdata
golang.org/x/tools/go/internal/gcimporter golang.org/x/tools/go/internal/gcimporter
@ -137,9 +137,9 @@ google.golang.org/appengine/internal/base
google.golang.org/appengine/internal/datastore google.golang.org/appengine/internal/datastore
google.golang.org/appengine/internal/log google.golang.org/appengine/internal/log
google.golang.org/appengine/internal/remote_api google.golang.org/appengine/internal/remote_api
# google.golang.org/genproto v0.0.0-20190716160619-c506a9f90610 # google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64
google.golang.org/genproto/googleapis/rpc/status google.golang.org/genproto/googleapis/rpc/status
# google.golang.org/grpc v1.22.1 # google.golang.org/grpc v1.23.0
google.golang.org/grpc google.golang.org/grpc
google.golang.org/grpc/codes google.golang.org/grpc/codes
google.golang.org/grpc/status google.golang.org/grpc/status