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
Open

net: Listen always uses nextPort() instead of the desired port on JS #31294

albrow opened this issue Apr 6, 2019 · 5 comments
Labels
arch-wasm WebAssembly issues NeedsFix The path to resolution is known, but the work has not been done. OS-JS
Milestone

Comments

@albrow
Copy link
Contributor

albrow 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
Copy link
Contributor Author

albrow 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
Copy link
Contributor Author

albrow 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
Copy link
Contributor

mikioh 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
Copy link
Contributor Author

albrow 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
Copy link
Contributor

mikioh 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 The path to resolution is known, but the work has not been done. 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
@dmitshur dmitshur added the arch-wasm WebAssembly issues label Oct 9, 2019
@rsc rsc modified the milestones: Go1.14, Backlog Oct 9, 2019
@rsc rsc unassigned mikioh Jun 23, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
arch-wasm WebAssembly issues NeedsFix The path to resolution is known, but the work has not been done. OS-JS
Projects
None yet
Development

No branches or pull requests

6 participants