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: Listen always uses nextPort() instead of the desired port on JS #31294

Open
albrow opened this issue Apr 6, 2019 · 5 comments

Comments

@albrow
Copy link
Contributor

commented Apr 6, 2019

What version of Go are you using (go version)?

$ go version
go version go1.12.1 darwin/amd64

Since this bug has to do with compiling to WebAssembly and running in Node.js, here is my Node.js version too:

$ node --version
v11.7.0

Does this issue reproduce with the latest release?

Yes.

What operating system and processor architecture are you using (go env)?

go env Output
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/alex/Library/Caches/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/alex/programming/go"
GOPROXY=""
GORACE=""
GOROOT="/Users/alex/.go"
GOTMPDIR=""
GOTOOLDIR="/Users/alex/.go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/h1/vhbpm31925nd0whbv4qd8mr00000gn/T/go-build857099932=/tmp/go-build -gno-record-gcc-switches -fno-common"

However, it's worth noting that the bug only occurs when you set GOOS=js GOARCH=wasm.

What did you do?

Consider the following Go program:

package main

import (
	"fmt"
	"net"
)

func main() {
	ln, err := net.Listen("tcp", "127.0.0.1:8080")
	if err != nil {
		panic(err)
	}
	defer ln.Close()
	fmt.Println(ln.Addr())
}

Run the program with the following command (From the Go WebAssembly Wiki):

GOOS=js GOARCH=wasm go run -exec="$(go env GOROOT)/misc/wasm/go_js_wasm_exec" main.go

What did you expect to see?

The program should output 127.0.0.1:8080 since that is the address I passed to net.Listen.

If you run the program with go run main.go (not compiling to WebAssembly) you see the output that I would expect.

What did you see instead?

127.0.0.1:1

I believe the root of the problem is the socket function in net_fake.go. It always uses nextPort() instead of using the port in the laddr argument.

@albrow albrow changed the title WebAssembly: `net.Listen` always uses `nextPort()` instead of the desired port WebAssembly: net.Listen always uses nextPort() instead of the desired port Apr 6, 2019

@albrow

This comment has been minimized.

Copy link
Contributor Author

commented Apr 6, 2019

@neelance, I think you have the most context here. Let me know if there's any way I can help!

@albrow

This comment has been minimized.

Copy link
Contributor Author

commented Apr 6, 2019

Here's another example of a program that actually uses the listener instead of just printing out ln.Addr():

package main

import (
	"fmt"
	"io/ioutil"
	"net"
)

func main() {
	ln, err := net.Listen("tcp", "127.0.0.1:8080")
	if err != nil {
		panic(err)
	}
	defer ln.Close()
	fmt.Println(ln.Addr())

	go func() {
		conn, err := net.Dial("tcp", "127.0.0.1:8080")
		if err != nil {
			panic(err)
		}
		defer conn.Close()
		if _, err := conn.Write([]byte("Hello!")); err != nil {
			panic(err)
		}
	}()

	fmt.Println("Waiting for new connections...")
	conn, err := ln.Accept()
	if err != nil {
		panic(err)
	}
	bytes, err := ioutil.ReadAll(conn)
	if err != nil {
		panic(err)
	}
	fmt.Println("Received: ", string(bytes))
}

Run with go run main.go:

127.0.0.1:8080
Waiting for new connections...
Received:  Hello!

Run with GOOS=js GOARCH=wasm go run -exec="$(go env GOROOT)/misc/wasm/go_js_wasm_exec" main.go:

127.0.0.1:1
Waiting for new connections...
panic: dial tcp 127.0.0.1:8080: Connection refused

goroutine 6 [running]:
main.main.func1()
	/Users/alex/programming/go/src/github.com/albrow/wasm-listen-port-bug/main.go:20 +0x25
created by main.main
	/Users/alex/programming/go/src/github.com/albrow/wasm-listen-port-bug/main.go:17 +0x17
exit status 2

Interestingly, it works if you change the code to net.Listen("tcp", "127.0.0.1:1") and net.Dial("tcp", "127.0.0.1:1") since that is the port first returned by nextPort().

@mikioh mikioh changed the title WebAssembly: net.Listen always uses nextPort() instead of the desired port net: Listen always uses nextPort() instead of the desired port on JS Apr 6, 2019

@mikioh

This comment has been minimized.

Copy link
Contributor

commented Apr 6, 2019

See #30324.

The package net on JS is fake and incomplete. I guess http://golang.org/cl/120958 fixes this issue.

@albrow

This comment has been minimized.

Copy link
Contributor Author

commented Apr 8, 2019

Yes, I understand the implementation is fake. Still, it seems that there was some effort to make it sort of work, and correcting the port numbers would make it a lot more useful.

Specifically, I'm writing some tests for Go code and I want to make sure it works when compiled to WebAssembly. There's a lot of code to test, but under the hood I am trying to dial a net.Listener. Since dialing (which is only a small part of the functionality I am trying to test) doesn't work correctly, the whole test fails.

If http://golang.org/cl/120958 fixes this I'm okay with waiting. Any idea when that might land?

@mikioh

This comment has been minimized.

Copy link
Contributor

commented Apr 9, 2019

Any idea when that might land?

Then, I will try to catch the Go 1.13 release train. Please be informed that it's not rare that CLs from alien contributors like me will take a bit long time for landing, sometimes a year or two, as CL 120958 was written during the last year's football world cup games and still has no review yet.

@mikioh mikioh added the OS-JS label Apr 9, 2019

@bcmills bcmills added the NeedsFix label Apr 11, 2019

@bcmills bcmills added this to the Go1.13 milestone Apr 11, 2019

@andybons andybons modified the milestones: Go1.13, Go1.14 Jul 8, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants
You can’t perform that action at this time.