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: ListenPacket cannot receive packets from non-localhost #66662

Open
rucarrol opened this issue Apr 3, 2024 · 1 comment
Open

net: ListenPacket cannot receive packets from non-localhost #66662

rucarrol opened this issue Apr 3, 2024 · 1 comment
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. OS-OpenBSD
Milestone

Comments

@rucarrol
Copy link

rucarrol commented Apr 3, 2024

Go version

go version go1.22.1 openbsd/amd64

Output of go env in your module/workspace:

GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/home/coder/.cache/go-build'
GOENV='/home/coder/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/coder/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/coder/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/home/coder/sdk/go1.22.1'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/home/coder/sdk/go1.22.1/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.22.1'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/dev/null'
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 -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build3938717940=/tmp/go-build -gno-record-gcc-switches

What did you do?

Consider the following program:

package main

import (
	"flag"
	"fmt"
	"net"
	"os"
)

var (
	iface = flag.String("bindto", "127.0.0.1", "Interface to bind to")
	proto = flag.String("proto", "1" , "Proto family")
)
func main() {
	flag.Parse()
	addrFamily := fmt.Sprintf("ip4:%s", *proto)
	conn, err := net.ListenPacket(addrFamily, *iface)
	if err != nil {
		fmt.Printf("Failed to listen: %v\n", err)
		os.Exit(1)
	}
	buf := make([]byte, 50)
	_, _, err = conn.ReadFrom(buf)
	if err != nil {
		fmt.Printf("Failed to read from socket: %v\n", err)
		os.Exit(1)
	}
	fmt.Printf("Got: %#v\n", buf)
}

What did you see happen?

On OpenBSD, 7.4, amd64 (Cross compiling from Linux/amd64 on 1.22.1), I did not see the packet arrive on the Listening Socket(Addresses retracted):

$ tcpdump -i vio0 -n -s1200 -c1 "icmp" &
[1] 64166
tcpdump: listening on vio0, link-type EN10MB

$ ./main -proto 1 -bindto XX.XX.XX.XX
15:34:39.618333 YY.YY.YY.YY > XX.XX.XX.XX: icmp: echo request
^C
[1]+  Done                    tcpdump -i vio0 -n -s1200 -c1 "icmp"

Note the lack of output. However if the traffic is generated on the same box, then we see packets arrive as expected:

$ tcpdump -i vio0 -n -s1200 -c1 "icmp" &
[1] 17457
tcpdump: listening on vio0, link-type EN10MB

$ ./main -proto 1 -bindto XX.XX.XX.XX &
[2] 65692


$ ping -c1 XX.XX.XX.XX
PING XX.XX.XX.XX(XX.XX.XX.XX): 56 data bytes
64 bytes from XX.XX.XX.XX: icmp_seq=0 ttl=255 time=0.918 ms
Got: []byte{0x0, 0x0, 0x98, 0x31, 0x39, 0xae, 0x0, 0x0, 0x5a, 0xc8, 0xbd, 0xa0, 0x80, 0x1d, 0x3c, 0x52, 0xae, 0xeb, 0x4c, 0x83, 0x69, 0xf5, 0x38, 0x42, 0xa7, 0x13, 0xf3, 0x65, 0x96, 0x42, 0xbd, 0xa0, 0x80, 0x1d, 0x3c, 0x52, 0xae, 0xeb, 0x4c, 0x83, 0x69, 0xf5, 0x38, 0x42, 0xa7, 0x13, 0xf3, 0x65, 0x96, 0x42}

--- XX.XX.XX.XX ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/std-dev = 0.918/0.918/0.918/0.000 ms
[2]+  Done                    ./main -proto 1 -bindto XX.XX.XX.XX
15:37:06.399667 YY.YY.YY.YY > XX.XX.XX.XX: icmp: echo request (DF)

This is unexpected, as we know the packet is arriving in userspace. If tcpdump can see the packet, and we can see the packets in Linux without issues, then we should also see a packet from net.ListenPacket in OpenBSD.

What did you expect to see?

This works as expected on Linux, where we bind to an external IP, and we see the ICMP (proto 1) packet arrive in both userspace, and at the connection:

$ sudo tcpdump -i any -n -s0 -c 1 "icmp" &
[1] 2049689
tcpdump: data link type LINUX_SLL2
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes

$ sudo ./main -proto 1 -bindto "192.168.0.254"
Got:  []byte{0x8, 0x0, 0xdd, 0x53, 0x2, 0x2f, 0x0, 0x1, 0x27, 0x59, 0xd, 0x66, 0x0, 0x0, 0x0, 0x0, 0x18, 0xea, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0xd, 0x66, 0x0, 0x0, 0x0, 0x0, 0x18, 0xea, 0xc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15}

$ 13:27:00.732378 net1  In  IP 192.168.0.187 > 192.168.0.254: ICMP echo request, id 559, seq 1, length 64
1 packet captured
2 packets received by filter
0 packets dropped by kernel
^C
[1]+  Done                    sudo tcpdump -i any -n -s0 -c 1 "icmp"
@seankhliao seankhliao changed the title net.ListenPacket: Cannot receive packets from non-localhost net: ListenPacket cannot receive packets from non-localhost Apr 3, 2024
@dmitshur dmitshur added OS-OpenBSD NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Apr 3, 2024
@dmitshur dmitshur added this to the Backlog milestone Apr 3, 2024
@dmitshur
Copy link
Contributor

dmitshur commented Apr 3, 2024

CC @golang/openbsd, @ianlancetaylor, @neild.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. OS-OpenBSD
Projects
None yet
Development

No branches or pull requests

2 participants