From 8eeea5ff08dc8c434ad2744533a324ad4b0a5de6 Mon Sep 17 00:00:00 2001 From: Lars-Christian Schulz Date: Sat, 23 Nov 2024 20:38:13 +0100 Subject: [PATCH] snet: test for Windows-specific error codes --- pkg/snet/BUILD.bazel | 2 ++ pkg/snet/snet.go | 8 +++----- pkg/snet/sock_error_posix.go | 32 ++++++++++++++++++++++++++++++ pkg/snet/sock_error_windows.go | 36 ++++++++++++++++++++++++++++++++++ 4 files changed, 73 insertions(+), 5 deletions(-) create mode 100644 pkg/snet/sock_error_posix.go create mode 100644 pkg/snet/sock_error_windows.go diff --git a/pkg/snet/BUILD.bazel b/pkg/snet/BUILD.bazel index f0f8a2a654..16c9f075db 100644 --- a/pkg/snet/BUILD.bazel +++ b/pkg/snet/BUILD.bazel @@ -13,6 +13,8 @@ go_library( "router.go", "scmp.go", "snet.go", + "sock_error_posix.go", + "sock_error_windows.go", "svcaddr.go", "udpaddr.go", "writer.go", diff --git a/pkg/snet/snet.go b/pkg/snet/snet.go index cc4c13d503..d8dca6221b 100644 --- a/pkg/snet/snet.go +++ b/pkg/snet/snet.go @@ -38,10 +38,8 @@ package snet import ( "context" - "errors" "net" "net/netip" - "syscall" "github.com/scionproto/scion/pkg/addr" "github.com/scionproto/scion/pkg/log" @@ -190,7 +188,7 @@ func listenUDPRange(addr *net.UDPAddr, start, end uint16) (*net.UDPConn, error) // by longer-lived applications, e.g., server applications. // // Ideally we would only take a standard ephemeral range, e.g., 32768-65535, - // Unfortunately, this range was ocuppied by the old dispatcher. + // Unfortunately, this range was occupied by the old dispatcher. // The default range for the dispatched ports is 31000-32767. // By configuration other port ranges may be defined and restricting to the default // range for applications may cause problems. @@ -208,12 +206,12 @@ func listenUDPRange(addr *net.UDPAddr, start, end uint16) (*net.UDPConn, error) if err == nil { return pconn, nil } - if errors.Is(err, syscall.EADDRINUSE) { + if errorIsAddrUnavailable(err) { continue } return nil, err } - return nil, serrors.Wrap("binding to port range", syscall.EADDRINUSE, + return nil, serrors.Wrap("binding to port range", ErrAddrInUse, "start", restrictedStart, "end", end) } diff --git a/pkg/snet/sock_error_posix.go b/pkg/snet/sock_error_posix.go new file mode 100644 index 0000000000..cb929b63cc --- /dev/null +++ b/pkg/snet/sock_error_posix.go @@ -0,0 +1,32 @@ +// Copyright 2024 OVGU Magdeburg +// +// 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. + +//go:build !windows + +package snet + +import ( + "errors" + "syscall" +) + +const ( + ErrAddrInUse = syscall.EADDRINUSE +) + +// errorIsAddrUnavailable checks whether the error returned from a syscall to +// bind indicates that the requested address is not available. +func errorIsAddrUnavailable(err error) bool { + return errors.Is(err, syscall.EADDRINUSE) +} diff --git a/pkg/snet/sock_error_windows.go b/pkg/snet/sock_error_windows.go new file mode 100644 index 0000000000..3346f32974 --- /dev/null +++ b/pkg/snet/sock_error_windows.go @@ -0,0 +1,36 @@ +// Copyright 2024 OVGU Magdeburg +// +// 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. + +//go:build windows + +package snet + +import ( + "errors" + + "golang.org/x/sys/windows" +) + +const ( + ErrAddrInUse = windows.WSAEADDRINUSE +) + +// errorIsAddrUnavailable checks whether the error returned from a syscall to +// bind indicates that the requested address is not available. +func errorIsAddrUnavailable(err error) bool { + // WSAEADDRINUSE is returned if another socket is bound to the same address. + // WSAEACCES is returned if another process is bound to the same address + // with exclusive access. + return errors.Is(err, windows.WSAEADDRINUSE) || errors.Is(err, windows.WSAEACCES) +}