Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

net/rpc: no way to get visibility into write errors (debugLog isn't exposed or changed) #71559

Closed
lattwood opened this issue Feb 4, 2025 · 9 comments
Labels
BugReport Issues describing a possible bug in the Go implementation. Unfortunate

Comments

@lattwood
Copy link

lattwood commented Feb 4, 2025

Go version

go version go1.23.1 darwin/arm64

Output of go env in your module/workspace:

GO111MODULE=''
GOARCH='arm64'
GOBIN=''
GOCACHE='/Users/loganattwood/Library/Caches/go-build'
GOENV='/Users/loganattwood/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMODCACHE='/Users/loganattwood/gopath/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='darwin'
GOPATH='/Users/loganattwood/gopath'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/opt/homebrew/Cellar/go/1.23.1/libexec'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='local'
GOTOOLDIR='/opt/homebrew/Cellar/go/1.23.1/libexec/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='go1.23.1'
GODEBUG=''
GOTELEMETRY='local'
GOTELEMETRYDIR='/Users/loganattwood/Library/Application Support/go/telemetry'
GCCGO='gccgo'
GOARM64='v8.0'
AR='ar'
CC='cc'
CXX='c++'
CGO_ENABLED='1'
GOMOD='/opt/homebrew/Cellar/go/1.23.1/libexec/src/go.mod'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/cr/cbrcy4x955v17hhkg5vwr3gh0000gq/T/go-build2283193740=/tmp/go-build -gno-record-gcc-switches -fno-common'

What did you do?

I was investigating this issue (I'm linking to a comment) hashicorp/yamux#143 (comment) that involved net/rpc.

The core of the issue is a Write error getting returned from the related codec was never going anywhere. The documentation for net/rpc.ServerCodec has WriteResponse returning an error: https://pkg.go.dev/net/rpc#ServerCodec

Requiring implementation of an interface to return an error implies that something is done with the error, and so I wanted to see the error that was getting returned. That's when I discovered that's controlled by net/rpc.debugLog. Unfortunately, that value is only ever read, and never written to.

The Gob Codec does do logging of errors-

log.Println("rpc: gob error encoding response:", err)

The jsonrpc Codec does not do logging of errors-

func (c *serverCodec) WriteResponse(r *rpc.Response, x any) error {

What did you see happen?

Errors were silenced, and there's no way to enable debugLog w/o modifying and recompiling the net/rpc package.

insert something tongue-in-cheek about proving a negative

What did you expect to see?

I expected a couple things

  • a way to enable net/rpc error logging that doesn't involve modifying the standard library and recompiling
  • some indicate there was an error returned from WriteResponse when replying to a net/rpc call
  • the various net/rpc codecs in the Go standard library be internally consistent wrt logging of errors
  • the (disabled) log messages would actually indicate there's an error (gob codec includes the word error in its log messages, but net/rpc just prefixes them with rpc:)
  • (wish list) when net/rpc calls WriteResponse on a codec and it returns an error, it should then call Close. Based on this comment in the documentation, this should not cause consistency issues- Close can be called multiple times and must be idempotent.
@gabyhelp gabyhelp added the BugReport Issues describing a possible bug in the Go implementation. label Feb 4, 2025
@seankhliao
Copy link
Member

As the package docs indicate, the package is frozen. I don't think any chance will be made here, sorry.

@seankhliao seankhliao closed this as not planned Won't fix, can't repro, duplicate, stale Feb 4, 2025
@lattwood
Copy link
Author

lattwood commented Feb 4, 2025

@seankhliao would it make sense to move The net/rpc package is frozen and is not accepting new features. to the header of the godoc for the page, and to be explicit about the fact that bugs will not be getting addressed any more?

if that extends even to security issues, can net/rpc be added to vulndb to encourage/force a migration away?

if need be i can open another issue.

@ianlancetaylor
Copy link
Member

We will still address bugs, but the fact that debugLog is not exposed is not a bug.

I sent https://go.dev/cl/646575 to move up the notice. Thanks for the suggestion.

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/646575 mentions this issue: net/rpc: move frozen notice to the start of the package doc

@lattwood
Copy link
Author

lattwood commented Feb 4, 2025

@ianlancetaylor would "errors returned when writing to the provided codec are silently dropped" be a bug?

edit: my comment about bugs not getting fixed stems from the original justification @robpike had for freezing it

The package has outstanding bugs that are hard to fix, and cannot support TLS without major work. So although it has a nice API and allows one to use native Go types without an IDL, it should probably be retired.

The proposal is to freeze the package, retire the many bugs filed against it, and add documentation indicating that it is frozen and that suggests alternatives such as GRPC.

heavily implies bugs will not be fixed going forward

#16844

@ianlancetaylor
Copy link
Member

Fair enough.

@lattwood
Copy link
Author

lattwood commented Feb 4, 2025

Not sure what to take away from that- should I make a PR so it always logs (fix the bug, which is opposite @robpike's rationale for freezing it), open a proposal for a louder warning/notice that net/rpc is frozen/support is deprecated, or do the go vulndb thing?

@ianlancetaylor
Copy link
Member

I've already sent a change to make it clearer that the package is frozen.

I don't see why this is a vulnerability, so vulndb doesn't seem appropriate.

I recommend that you copy the package into your source tree, and edit it as you see fit. It doesn't depend on any internal standard library APIs, so copying it should be straightforward.

gopherbot pushed a commit that referenced this issue Feb 5, 2025
For #71559

Change-Id: I68b9518a26cab75789d596839267abab7997bc2c
Reviewed-on: https://go-review.googlesource.com/c/go/+/646575
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Rob Pike <r@golang.org>
Auto-Submit: Ian Lance Taylor <iant@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Commit-Queue: Ian Lance Taylor <iant@google.com>
tgross pushed a commit to hashicorp/net-rpc-msgpackrpc that referenced this issue Feb 24, 2025
It turns out when `net/rpc` calls `WriteResponse`, it [**doesn't do anything with the error**](https://github.com/golang/go/blob/cb47156e90cac6b1030d747f1ccd433c00494dfc/src/net/rpc/server.go#L359-L362)! (it does correctly propagate errors when `WriteRequest` is called though)

This means this codec needs to handle connection disposal, because there's no way for someone using `net/rpc` to find out about the error and handle it- we're in the twilight zone.

Additionally, because `net/rpc` is frozen upstream, there is a lack of desire to fix even the logging aspect, let alone the underlying defect: golang/go#71559

The `WriteResponse` and `WriteRequest` methods both use the same underlying `write` method, so this fix took three commits-

* adding the first test coverage to this package, to prove de-DRYing doesn't break anything
* de-DRYing by inlining `write` into `WriteResponse` and `WriteRequest`
* the actual fix, along with a test for it

This puts an end to two years of "spooky behaviour at a distance" on our large and geographically distributed Nomad cluster.

Fixes: hashicorp/nomad#23305
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
BugReport Issues describing a possible bug in the Go implementation. Unfortunate
Projects
None yet
Development

No branches or pull requests

5 participants