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

x/net/internal/socket: (*ipv4.PacketConn).ReadFrom() returns nil source on go1.9 (android-arm64) #22115

Closed
tmm1 opened this issue Oct 3, 2017 · 8 comments

Comments

@tmm1
Copy link
Contributor

tmm1 commented Oct 3, 2017

Please answer these questions before submitting your issue. Thanks!

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

go version go1.9 darwin/amd64

Does this issue reproduce with the latest release?

Yes

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

LD=aach64-linux-android-ld CC=aarch64-linux-android-gcc GOOS=android GOARCH=arm64

What did you do?

I'm using this test program that prints out whenever mDNS broadcast packets are seen on the network:

package main

import (
	"log"
	"net"

	"golang.org/x/net/ipv4"
)

func main() {
	mdnsGroupIPv4 := net.IPv4(224, 0, 0, 251)
	mdnsWildcardAddrIPv4 := &net.UDPAddr{
		IP:   net.ParseIP("224.0.0.0"),
		Port: 5353,
	}

	udpConn, err := net.ListenUDP("udp4", mdnsWildcardAddrIPv4)
	if err != nil {
		log.Fatal(err)
	}

	pkConn := ipv4.NewPacketConn(udpConn)
	pkConn.SetControlMessage(ipv4.FlagInterface, true)

	ifaces, err := net.Interfaces()
	if err != nil {
		log.Fatal(err)
	}
	for _, iface := range ifaces {
		pkConn.JoinGroup(&iface, &net.UDPAddr{IP: mdnsGroupIPv4})
	}

	buf := make([]byte, 65536)
	for {
		n, _, from, err := pkConn.ReadFrom(buf)
		if err != nil {
			log.Fatal(err)
		}

		log.Printf("got %v bytes from %+v", n, from)
	}
}

What did you expect to see?

This program works as expected on most platforms (linux, darwin, freebsd, windows, android) on golang 1.8.

Since upgrading to golang 1.9 (and upgrading x/net to master), it no longer works as expected on android/arm64.

What did you see instead?

On golang 1.9 w/ golang/net@3470a06:

2017/10/03 00:07:45 got 66 bytes from 10.0.1.136:5353
2017/10/03 00:07:46 got 66 bytes from 10.0.1.136:5353

On golang 1.9 w/ golang/net@b7a1f62:

2017/10/03 00:08:15 got 66 bytes from :5353
2017/10/03 00:08:16 got 66 bytes from :5353

For some reason, the source IP is no longer populated:

&net.UDPAddr{IP:net.IP(nil), Port:5353, Zone:""}

The same issue is present with *ipv4.PacketConn after golang/net@48359f4

cc @mikioh

@mikioh
Copy link
Contributor

mikioh commented Oct 3, 2017

I'm not sure what's going on.

  • Can you please try both go1.8- and go1.9-based executable on the same node; android (which version?) linux/arm64.
  • When you try, please dump the address with default format like the following: s/log.Printf("got %v bytes from %+v", n, from)/log.Printf("got %v bytes from %#v", n, from)/

@tmm1
Copy link
Contributor Author

tmm1 commented Oct 3, 2017

I ran my tests on the same node, with golang 1.9 but two different revisions of x/net. Would you like me to try golang 1.8 as well? With which revision of x/net?

I'm seeing this behavior on an NVidia SHIELD android TV, running a variant of Android 7.1.1

Linux localhost 3.10.96+ #1 SMP PREEMPT Fri Sep 22 18:32:54 PDT 2017 aarch64

@tmm1
Copy link
Contributor Author

tmm1 commented Oct 3, 2017

I tried %#v earlier and it outputs &net.UDPAddr{IP:net.IP(nil), Port:5353, Zone:""}

@mikioh
Copy link
Contributor

mikioh commented Oct 3, 2017

Would you like me to try golang 1.8 as well? With which revision of x/net?

Yes, thanks. The same revision is fine because packages in x/net switch the codepath at run time.

I tried %#v ...

Oh, I missed that, thanks. Then, there's probably something wrong on parseInetAddr in internal/socket/sys_posix.go. I'm not an Android user and have no Android stuff. Do you have a spare time for diving into the thing a bit? If you have a time, can you please dump and report back the raw socket address in parseInetAddr?

--- a/internal/socket/sys_posix.go
+++ b/internal/socket/sys_posix.go
@@ -67,6 +67,10 @@ func parseInetAddr(b []byte, network string) (net.Addr, error) {
        if len(b) < 2 {
                return nil, errors.New("invalid address")
        }
+       for i := range b {
+               print(b[i], " ")
+       }
+       println(network)
        var af int
        switch runtime.GOOS {

Thanks.

@tmm1
Copy link
Contributor Author

tmm1 commented Oct 3, 2017

@mikioh Thanks for the pointer. parseInetAddr() has a runtime.GOOS switch statement. If I add "android" to the list, it fixes my issue. Probably it should be added to the switch statements in marshalSockaddr() as well.

@mikioh
Copy link
Contributor

mikioh commented Oct 3, 2017

Good. Do you want to send a CL?

@mikioh mikioh changed the title x/net: (*ipv4.PacketConn).ReadFrom() returns nil source on go1.9 (android-arm64) x/net/internal/socket: (*ipv4.PacketConn).ReadFrom() returns nil source on go1.9 (android-arm64) Oct 3, 2017
@tmm1
Copy link
Contributor Author

tmm1 commented Oct 3, 2017 via email

@gopherbot
Copy link
Contributor

Change https://golang.org/cl/67770 mentions this issue: internal/socket: make ipv4, ipv6 and icmp work again on android

@golang golang locked and limited conversation to collaborators Oct 4, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants