Skip to content

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

@skladd

Description

@skladd

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeNeedsFixThe path to resolution is known, but the work has not been done.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions