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/sys/unix: support AF_CAN in anyToSockaddr #40842

Closed
skladd opened this issue Aug 17, 2020 · 4 comments
Closed

x/sys/unix: support AF_CAN in anyToSockaddr #40842

skladd opened this issue Aug 17, 2020 · 4 comments
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@skladd
Copy link

skladd commented Aug 17, 2020

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

$ go version
go version go1.14.3 linux/amd64

Does this issue reproduce with the latest release?

yes

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

go env Output
$ go env
GOARCH="amd64"
GOOS="linux"
CGO_ENABLED="1"

What did you do?

Calling e.g. unix.Recvmsg for a SocketCAN socket (AF_CAN)

Example program
First set up VCAN interface and generate data (via canutils):
$ sudo ip link add dev vcan0 type vcan && sudo ip link set up vcan0
$ cangen vcan0 -g 4 -I 42A -L 2 -D 1234 -v -v
package main

import (
	"fmt"
	"net"

	"golang.org/x/sys/unix"
)

const ifaceName = "vcan0"

func main() {
	var (
		err   error
		iface *net.Interface
		fd    int
	)

	if iface, err = net.InterfaceByName(ifaceName); err != nil {
		panic(err)
	}

	if fd, err = unix.Socket(unix.AF_CAN, unix.SOCK_RAW, unix.CAN_RAW); err != nil {
		panic(err)
	}

	if err = unix.SetsockoptInt(fd, unix.SOL_SOCKET, unix.SO_TIMESTAMPNS, 1); err != nil {
		panic(err)
	}

	if err = unix.Bind(fd, &unix.SockaddrCAN{Ifindex: iface.Index}); err != nil {
		panic(err)
	}

	b := make([]byte, 256)
	oob := make([]byte, 256)
	var (
		n, oobn, recvflags int
		from unix.Sockaddr
	)

	// returns error
	n, oobn, recvflags, from, err = unix.Recvmsg(fd, b, oob, 0)

	fmt.Printf("unix.Recvmsg() b: %v, oob: %v, recvflags: %v, from: %v, err: \"%v\"\n", b[:n], oob[:oobn], recvflags, from, err)
}

What did you expect to see?

unix.Recvmsg() b: [42 4 0 0 2 0 0 0 18 52 0 0 0 0 0 0], oob: [32 0 0 0 0 0 0 0 1 0 0 0 29 0 0 0 3 150 58 95 0 0 0 0 178 148 5 0 0 0 0 0], recvflags: 4, from: &{7 0 0 {0 0 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]}}, err: "<nil>"

What did you see instead?

Method returns error EAFNOSUPPORT "address family not supported by protocol" and from <nil>.

unix.Recvmsg() b: [42 4 0 0 2 0 0 0 18 52 0 0 0 0 0 0], oob: [32 0 0 0 0 0 0 0 1 0 0 0 29 0 0 0 65 150 58 95 0 0 0 0 174 73 9 0 0 0 0 0], recvflags: 4, from: <nil>, err: "address family not supported by protocol"

Comments

Obviously, private unix.anyToSockaddr is called by unix.Recvmsg and returns EAFNOSUPPORT as AF_CAN is not yet supported. SockaddrCAN and AF_CAN support was added via #16188 by @ianlancetaylor and @elliotmr.

Perhaps something like

	case AF_CAN:
		pp := (*RawSockaddrCAN)(unsafe.Pointer(rsa))
		sa := &SockaddrCAN{
			Ifindex: int(pp.Ifindex),
		}
		return sa, nil

in the switch statement in anyToSockaddr() would be sufficient.

@gopherbot gopherbot added this to the Unreleased milestone Aug 17, 2020
@tklauser
Copy link
Member

	case AF_CAN:
		pp := (*RawSockaddrCAN)(unsafe.Pointer(rsa))
		sa := &SockaddrCAN{
			Ifindex: int(pp.Ifindex),
		}
		return sa, nil

in the switch statement in anyToSockaddr() would be sufficient.

I think you'll also need to set sa.Addr, other than that it looks like this should be sufficient. Want to send a CL?

@skladd
Copy link
Author

skladd commented Aug 18, 2020

SockaddrCAN has no field Addr, but I do not know what has to be done here. In fact, I am not really interested in the returned from socket. Instead, I stumbled on the EAFNOSUPPORT error.

CLA is signed.

@tklauser
Copy link
Member

SockaddrCAN has no field Addr, but I do not know what has to be done here.

Right. My mistake, I was looking at RawSockaddrCAN.

I think we need to fill sa.RxID and sa.TxID from pp.Addr, basically reverse what (*SockaddrCAN).sockaddr() does.

skladd added a commit to skladd/sys that referenced this issue Aug 18, 2020
Add AF_CAN support to anyToSockaddr()

Fixes golang/go#40842
@gopherbot
Copy link

Change https://golang.org/cl/248977 mentions this issue: unix: extend AF_CAN socket support

@dmitshur dmitshur added NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. NeedsFix The path to resolution is known, but the work has not been done. and removed NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Aug 18, 2020
@dmitshur dmitshur changed the title x/sys: support AF_CAN in anyToSockaddr x/sys/unix: support AF_CAN in anyToSockaddr Aug 18, 2020
@golang golang locked and limited conversation to collaborators Aug 19, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants