diff --git a/private/underlay/sockctrl/BUILD.bazel b/private/underlay/sockctrl/BUILD.bazel index 67e19ae27d..f1d0dfe0db 100644 --- a/private/underlay/sockctrl/BUILD.bazel +++ b/private/underlay/sockctrl/BUILD.bazel @@ -4,9 +4,55 @@ go_library( name = "go_default_library", srcs = [ "sockctrl.go", + "sockctrl_windows.go", "sockopt.go", + "sockopt_windows.go", ], importpath = "github.com/scionproto/scion/private/underlay/sockctrl", visibility = ["//visibility:public"], - deps = ["//pkg/private/serrors:go_default_library"], + deps = select({ + "@io_bazel_rules_go//go/platform:aix": [ + "//pkg/private/serrors:go_default_library", + ], + "@io_bazel_rules_go//go/platform:android": [ + "//pkg/private/serrors:go_default_library", + ], + "@io_bazel_rules_go//go/platform:darwin": [ + "//pkg/private/serrors:go_default_library", + ], + "@io_bazel_rules_go//go/platform:dragonfly": [ + "//pkg/private/serrors:go_default_library", + ], + "@io_bazel_rules_go//go/platform:freebsd": [ + "//pkg/private/serrors:go_default_library", + ], + "@io_bazel_rules_go//go/platform:illumos": [ + "//pkg/private/serrors:go_default_library", + ], + "@io_bazel_rules_go//go/platform:ios": [ + "//pkg/private/serrors:go_default_library", + ], + "@io_bazel_rules_go//go/platform:js": [ + "//pkg/private/serrors:go_default_library", + ], + "@io_bazel_rules_go//go/platform:linux": [ + "//pkg/private/serrors:go_default_library", + ], + "@io_bazel_rules_go//go/platform:netbsd": [ + "//pkg/private/serrors:go_default_library", + ], + "@io_bazel_rules_go//go/platform:openbsd": [ + "//pkg/private/serrors:go_default_library", + ], + "@io_bazel_rules_go//go/platform:plan9": [ + "//pkg/private/serrors:go_default_library", + ], + "@io_bazel_rules_go//go/platform:solaris": [ + "//pkg/private/serrors:go_default_library", + ], + "@io_bazel_rules_go//go/platform:windows": [ + "//pkg/private/serrors:go_default_library", + ], + "//conditions:default": [], + }), ) diff --git a/private/underlay/sockctrl/sockctrl.go b/private/underlay/sockctrl/sockctrl.go index 2faeef054a..af9dc41692 100644 --- a/private/underlay/sockctrl/sockctrl.go +++ b/private/underlay/sockctrl/sockctrl.go @@ -12,11 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:build go1.9 -// +build go1.9 +// In Windows, SetSockOptInt and GetSockOptInt require syscall.Handle instead of int. +//go:build !windows -// This version of sockctrl is for Go versions >= 1.9, where the socket FDs are -// accessible via RawConn.Control(). package sockctrl import ( diff --git a/private/underlay/sockctrl/sockctrl_windows.go b/private/underlay/sockctrl/sockctrl_windows.go new file mode 100644 index 0000000000..81fd84c7bb --- /dev/null +++ b/private/underlay/sockctrl/sockctrl_windows.go @@ -0,0 +1,43 @@ +// Copyright 2024 ETH Zurich +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// In Windows, SetSockOptInt and GetSockOptInt require syscall.Handle instead of int. +//go:build windows + +package sockctrl + +import ( + "net" + "syscall" + + "github.com/scionproto/scion/pkg/private/serrors" +) + +func SockControl(c *net.UDPConn, f func(syscall.Handle) error) error { + rawConn, err := c.SyscallConn() + if err != nil { + return serrors.Wrap("sockctrl: error accessing raw connection", err) + } + var ctrlErr error + err = rawConn.Control(func(fd uintptr) { + ctrlErr = f(syscall.Handle(fd)) + }) + if err != nil { + return serrors.Wrap("sockctrl: RawConn.Control error", err) + } + if ctrlErr != nil { + return serrors.Wrap("sockctrl: control function error", ctrlErr) + } + return nil +} diff --git a/private/underlay/sockctrl/sockopt.go b/private/underlay/sockctrl/sockopt.go index cbf9339f06..d5b56e5cfc 100644 --- a/private/underlay/sockctrl/sockopt.go +++ b/private/underlay/sockctrl/sockopt.go @@ -12,6 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. +// In Windows, SetSockOptInt and GetSockOptInt require syscall.Handle instead of int. +//go:build !windows + package sockctrl import ( diff --git a/private/underlay/sockctrl/sockopt_windows.go b/private/underlay/sockctrl/sockopt_windows.go new file mode 100644 index 0000000000..8a9ceb07b8 --- /dev/null +++ b/private/underlay/sockctrl/sockopt_windows.go @@ -0,0 +1,39 @@ +// Copyright 2024 ETH Zurich +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// In Windows, SetSockOptInt and GetSockOptInt require syscall.Handle instead of int. +//go:build windows + +package sockctrl + +import ( + "net" + "syscall" +) + +func GetsockoptInt(c *net.UDPConn, level, opt int) (int, error) { + var val int + err := SockControl(c, func(fd syscall.Handle) error { + var err error + val, err = syscall.GetsockoptInt(fd, level, opt) + return err + }) + return val, err +} + +func SetsockoptInt(c *net.UDPConn, level, opt, value int) error { + return SockControl(c, func(fd syscall.Handle) error { + return syscall.SetsockoptInt(fd, level, opt, value) + }) +}