diff --git a/calnex/verify/checks/ping_test.go b/calnex/verify/checks/ping_test.go index 0a29b3c5..def38194 100644 --- a/calnex/verify/checks/ping_test.go +++ b/calnex/verify/checks/ping_test.go @@ -1,6 +1,3 @@ -//go:build !race -// +build !race - /* Copyright (c) Facebook, Inc. and its affiliates. diff --git a/clock/clock_386.go b/clock/clock_386.go deleted file mode 100644 index 55061a2a..00000000 --- a/clock/clock_386.go +++ /dev/null @@ -1,35 +0,0 @@ -//go:build 386 - -/* -Copyright (c) Facebook, Inc. and its affiliates. - -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. -*/ - -package clock - -import ( - "time" - - "golang.org/x/sys/unix" -) - -func setFreq(tx *unix.Timex, freqPPB float64) { - // man(2) clock_adjtime, turn ppb to ppm - tx.Freq = int32(freqPPB * PPBToTimexPPM) -} - -func setTime(tx *unix.Timex, sec, usec time.Duration) { - tx.Time.Sec = int32(sec) - tx.Time.Usec = int32(usec) -} diff --git a/clock/clock_64bit.go b/clock/clock_64bit.go deleted file mode 100644 index 9ab5701d..00000000 --- a/clock/clock_64bit.go +++ /dev/null @@ -1,35 +0,0 @@ -//go:build linux && !386 - -/* -Copyright (c) Facebook, Inc. and its affiliates. - -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. -*/ - -package clock - -import ( - "time" - - "golang.org/x/sys/unix" -) - -func setFreq(tx *unix.Timex, freqPPB float64) { - // man(2) clock_adjtime, turn ppb to ppm - tx.Freq = int64(freqPPB * PPBToTimexPPM) -} - -func setTime(tx *unix.Timex, sec, usec time.Duration) { - tx.Time.Sec = int64(sec) - tx.Time.Usec = int64(usec) -} diff --git a/clock/clock_64bit_darwin.go b/clock/clock_setters.go similarity index 74% rename from clock/clock_64bit_darwin.go rename to clock/clock_setters.go index 738c9e7c..4b0514a5 100644 --- a/clock/clock_64bit_darwin.go +++ b/clock/clock_setters.go @@ -1,5 +1,3 @@ -//go:build darwin && !386 - /* Copyright (c) Facebook, Inc. and its affiliates. @@ -24,11 +22,17 @@ import ( "github.com/facebook/time/phc/unix" ) +type timexInt interface{ ~int32 | ~int64 } + +func setTimexField[T timexInt](field *T, val float64) { + *field = T(val) +} + func setFreq(tx *unix.Timex, freqPPB float64) { - tx.Freq = int64(freqPPB * PPBToTimexPPM) + setTimexField(&tx.Freq, freqPPB*PPBToTimexPPM) } func setTime(tx *unix.Timex, sec, usec time.Duration) { - tx.Time.Sec = int64(sec) - tx.Time.Usec = int32(usec) + setTimexField(&tx.Time.Sec, float64(sec)) + setTimexField(&tx.Time.Usec, float64(usec)) } diff --git a/cmd/ntpcheck/cmd/utils_track.go b/cmd/ntpcheck/cmd/utils_track.go index 3061fa85..29b616ec 100644 --- a/cmd/ntpcheck/cmd/utils_track.go +++ b/cmd/ntpcheck/cmd/utils_track.go @@ -20,8 +20,8 @@ import ( "fmt" "time" + "github.com/facebook/time/phc/unix" "github.com/spf13/cobra" - "golang.org/x/sys/unix" ) func getRawMonotonic() float64 { diff --git a/ntp/responder/server/server_darwin_test.go b/ntp/responder/server/server_darwin_test.go deleted file mode 100644 index 7cfed46c..00000000 --- a/ntp/responder/server/server_darwin_test.go +++ /dev/null @@ -1,46 +0,0 @@ -/* -Copyright (c) Facebook, Inc. and its affiliates. - -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. -*/ - -package server - -import ( - "net" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestCheckIP(t *testing.T) { - iface, err := net.InterfaceByName("lo0") - require.NoError(t, err) - - ip := net.ParseIP("127.0.0.1") - assigned, err := checkIP(iface, &ip) - - require.NoError(t, err) - require.True(t, assigned) -} - -func TestCheckIPFalse(t *testing.T) { - iface, err := net.InterfaceByName("lo0") - require.NoError(t, err) - - ip := net.ParseIP("8.8.8.8") - assigned, err := checkIP(iface, &ip) - - require.NoError(t, err) - require.False(t, assigned) -} diff --git a/ntp/responder/server/server_freebsd.go b/ntp/responder/server/server_freebsd.go deleted file mode 100644 index b4c71009..00000000 --- a/ntp/responder/server/server_freebsd.go +++ /dev/null @@ -1,83 +0,0 @@ -/* -Copyright (c) Facebook, Inc. and its affiliates. - -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. -*/ - -package server - -import ( - "fmt" - "net" - "os/exec" - "time" -) - -func addIfaceIP(iface *net.Interface, addr *net.IP) error { - // Check if IP is assigned: - assigned, err := checkIP(iface, addr) - if err != nil { - return err - } - if assigned { - return nil - } - - var mask int - var proto string - if v4 := addr.To4(); v4 == nil { - proto = "inet6" - mask = ipv6Mask - } else { - proto = "inet" - mask = ipv4Mask - } - - cmd := exec.Command("ifconfig", iface.Name, proto, "alias", fmt.Sprintf("%s/%d", addr.String(), mask)) - fmt.Println(cmd.Args) - if err := cmd.Run(); err != nil { - return fmt.Errorf("can't add address: %w", err) - } - return nil -} - -func deleteIfaceIP(iface *net.Interface, addr *net.IP) error { - // Check if IP is assigned: - assigned, err := checkIP(iface, addr) - if err != nil { - return err - } - if !assigned { - return nil - } - - var proto string - if v4 := addr.To4(); v4 == nil { - proto = "inet6" - } else { - proto = "inet" - } - - cmd := exec.Command("ifconfig", iface.Name, proto, "-alias", addr.String()) - if err := cmd.Run(); err != nil { - return fmt.Errorf("can't remove address: %w", err) - } - - return nil -} - -// PHCOffset periodically checks for PHC-SYS offset and updates it in the config -// PHC reading is not supported on FreeBSD -func phcOffset(iface string) (time.Duration, error) { - return 0, nil -} diff --git a/ntp/responder/server/server_darwin.go b/ntp/responder/server/server_notlinux.go similarity index 96% rename from ntp/responder/server/server_darwin.go rename to ntp/responder/server/server_notlinux.go index 85ce6390..d3ba134d 100644 --- a/ntp/responder/server/server_darwin.go +++ b/ntp/responder/server/server_notlinux.go @@ -1,3 +1,5 @@ +//go:build !linux + /* Copyright (c) Facebook, Inc. and its affiliates. @@ -76,7 +78,7 @@ func deleteIfaceIP(iface *net.Interface, addr *net.IP) error { } // PHCOffset periodically checks for PHC-SYS offset and updates it in the config -// PHC reading is not supported on Darwin +// PHC reading is not supported on this platform func phcOffset(_ string) (time.Duration, error) { return 0, nil } diff --git a/ntp/responder/server/server_freebsd_test.go b/ntp/responder/server/server_notlinux_test.go similarity index 98% rename from ntp/responder/server/server_freebsd_test.go rename to ntp/responder/server/server_notlinux_test.go index 7cfed46c..23fc95d0 100644 --- a/ntp/responder/server/server_freebsd_test.go +++ b/ntp/responder/server/server_notlinux_test.go @@ -1,3 +1,5 @@ +//go:build !linux + /* Copyright (c) Facebook, Inc. and its affiliates. diff --git a/phc/unix/linux.go b/phc/unix/linux.go index 07a6639e..1f2aabe8 100644 --- a/phc/unix/linux.go +++ b/phc/unix/linux.go @@ -192,6 +192,7 @@ const ( SYS_CLOCK_SETTIME = unix.SYS_CLOCK_SETTIME //nolint:revive TIME_OK = unix.TIME_OK //nolint:revive CLOCK_BOOTTIME = unix.CLOCK_BOOTTIME //nolint:revive + CLOCK_MONOTONIC_RAW = unix.CLOCK_MONOTONIC_RAW //nolint:revive ) var ( diff --git a/phc/unix/notlinux.go b/phc/unix/notlinux.go index 851cc793..89612937 100644 --- a/phc/unix/notlinux.go +++ b/phc/unix/notlinux.go @@ -34,9 +34,11 @@ type Timex struct { // Linux-only constants that need stub values on Darwin // //nolint:revive +//nolint:revive const ( - TIME_OK = 0 - CLOCK_BOOTTIME = 7 + TIME_OK = 0 + CLOCK_BOOTTIME = 7 + CLOCK_MONOTONIC_RAW = 4 ) // FdToClockID is not supported on non-linux. diff --git a/phc/unix/types.go b/phc/unix/types.go index 68b4f386..a8034925 100644 --- a/phc/unix/types.go +++ b/phc/unix/types.go @@ -165,10 +165,9 @@ const ( POLLPRI = unix.POLLPRI SizeofPtr = unix.SizeofPtr SizeofSockaddrInet4 = unix.SizeofSockaddrInet4 - SOCK_DGRAM = unix.SOCK_DGRAM //nolint:revive - SOL_SOCKET = unix.SOL_SOCKET //nolint:revive - SO_RCVTIMEO = unix.SO_RCVTIMEO //nolint:revive - SO_TIMESTAMP = unix.SO_TIMESTAMP //nolint:revive - CLOCK_REALTIME = unix.CLOCK_REALTIME //nolint:revive - CLOCK_MONOTONIC_RAW = unix.CLOCK_MONOTONIC_RAW //nolint:revive + SOCK_DGRAM = unix.SOCK_DGRAM //nolint:revive + SOL_SOCKET = unix.SOL_SOCKET //nolint:revive + SO_RCVTIMEO = unix.SO_RCVTIMEO //nolint:revive + SO_TIMESTAMP = unix.SO_TIMESTAMP //nolint:revive + CLOCK_REALTIME = unix.CLOCK_REALTIME //nolint:revive ) diff --git a/timestamp/timestamp_freebsd.go b/timestamp/timestamp_freebsd.go deleted file mode 100644 index 77299700..00000000 --- a/timestamp/timestamp_freebsd.go +++ /dev/null @@ -1,92 +0,0 @@ -/* -Copyright (c) Facebook, Inc. and its affiliates. - -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. -*/ - -package timestamp - -import ( - "encoding/binary" - "fmt" - "net" - "time" - "unsafe" - - "golang.org/x/sys/unix" -) - -// unix.Cmsghdr size differs depending on platform -var socketControlMessageHeaderOffset = binary.Size(unix.Cmsghdr{}) - -var timestamping = unix.SO_TIMESTAMP - -// Here we have basic HW and SW timestamping support - -// byteToTime converts bytes into a timestamp -func byteToTime(data []byte) (time.Time, error) { - // freebsd supports only SO_TIMESTAMP mode, which returns timeval - timeval := (*unix.Timeval)(unsafe.Pointer(&data[0])) - return time.Unix(timeval.Unix()), nil -} - -/* -scmDataToTime parses SocketControlMessage Data field into time.Time. -*/ -func scmDataToTime(data []byte) (ts time.Time, err error) { - size := binary.Size(unix.Timeval{}) - - ts, err = byteToTime(data[0:size]) - if err != nil { - return ts, err - } - if ts.UnixNano() == 0 { - return ts, fmt.Errorf("got zero timestamp") - } - - return ts, nil -} - -// socketControlMessageTimestamp parses timestamp from control message -func socketControlMessageTimestamp(b []byte, _ int) (time.Time, error) { - return scmDataToTime(b[unix.CmsgSpace(0):]) -} - -// socketControlMessageDrops is not implemented for freebsd -func socketControlMessageDrops(b []byte, _ int) uint32 { - return 0 -} - -// EnableSWTimestampsRx enables SW RX timestamps on the socket -func EnableSWTimestampsRx(connFd int) error { - // Allow reading of SW timestamps via socket - return unix.SetsockoptInt(connFd, unix.SOL_SOCKET, timestamping, 1) -} - -// EnableTimestamps enables timestamps on the socket based on requested type -func EnableTimestamps(ts Timestamp, connFd int, _ *net.Interface) error { - switch ts { - case SW: - if err := EnableSWTimestampsRx(connFd); err != nil { - return fmt.Errorf("Cannot enable software timestamps: %w", err) - } - default: - return fmt.Errorf("Unrecognized timestamp type: %s", ts) - } - return nil -} - -// EnableRXQueueOverflow is not implemented for freebsd -func EnableRXQueueOverflow(connFd int) error { - return err.Errorf("RX queue overflow is not supported on freebsd") -} diff --git a/timestamp/timestamp_freebsd_test.go b/timestamp/timestamp_freebsd_test.go deleted file mode 100644 index bdbb1601..00000000 --- a/timestamp/timestamp_freebsd_test.go +++ /dev/null @@ -1,117 +0,0 @@ -/* -Copyright (c) Facebook, Inc. and its affiliates. - -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. -*/ - -package timestamp - -import ( - "fmt" - "net" - "testing" - "time" - - "github.com/stretchr/testify/require" - "golang.org/x/sys/unix" -) - -func Test_byteToTime(t *testing.T) { - timeb := []byte{145, 131, 229, 97, 0, 0, 0, 0, 203, 178, 14, 0, 0, 0, 0, 0} - res, err := byteToTime(timeb) - require.Nil(t, err) - - tv := &unix.Timeval{Sec: 1642431377, Usec: 963275} - require.Equal(t, time.Unix(tv.Unix()).UnixNano(), res.UnixNano()) -} - -func TestEnableSWTimestampsRx(t *testing.T) { - // listen to incoming udp packets - conn, err := net.ListenUDP("udp", &net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: 0}) - require.NoError(t, err) - defer conn.Close() - - connFd, err := ConnFd(conn) - require.NoError(t, err) - - // Allow reading of kernel timestamps via socket - err = EnableSWTimestampsRx(connFd) - require.NoError(t, err) - - // Check that socket option is set - kernelTimestampsEnabled, err := unix.GetsockoptInt(connFd, unix.SOL_SOCKET, unix.SO_TIMESTAMP) - require.NoError(t, err) - - // To be enabled must be > 0 - require.Greater(t, kernelTimestampsEnabled, 0, "Kernel timestamps are not enabled") -} - -func TestEnableTimestamps(t *testing.T) { - // listen to incoming udp packets - conn, err := net.ListenUDP("udp", &net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: 0}) - require.NoError(t, err) - defer conn.Close() - - connFd, err := ConnFd(conn) - require.NoError(t, err) - - // SOFTWARE - // Allow reading of kernel timestamps via socket - err = EnableTimestamps(SW, connFd, &net.Interface{Name: "lo", Index: 1}) - require.NoError(t, err) - - // Check that socket option is set - kernelTimestampsEnabled, err := unix.GetsockoptInt(connFd, unix.SOL_SOCKET, unix.SO_TIMESTAMP) - require.NoError(t, err) - - // To be enabled must be > 0 - require.Greater(t, kernelTimestampsEnabled, 0, "Kernel timestamps are not enabled") - - // HARDWARE - err = EnableTimestamps(HW, connFd, &net.Interface{Name: "lo", Index: 1}) - require.Equal(t, fmt.Errorf("Unrecognized timestamp type: %s", HW), err) -} - -func TestReadPacketWithRXTimestamp(t *testing.T) { - request := []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 42} - // listen to incoming udp packets - conn, err := net.ListenUDP("udp", &net.UDPAddr{IP: net.ParseIP("localhost"), Port: 0}) - require.NoError(t, err) - defer conn.Close() - - // get connection file descriptor - connFd, err := ConnFd(conn) - require.NoError(t, err) - - // Allow reading of kernel timestamps via socket - err = EnableSWTimestampsRx(connFd) - require.NoError(t, err) - - err = unix.SetNonblock(connFd, false) - require.NoError(t, err) - - // Send a client request - timeout := 1 * time.Second - cconn, err := net.DialTimeout("udp", conn.LocalAddr().String(), timeout) - require.NoError(t, err) - defer cconn.Close() - _, err = cconn.Write(request) - require.NoError(t, err) - - // read kernel timestamp from incoming packet - data, returnaddr, nowKernelTimestamp, err := ReadPacketWithRXTimestamp(connFd) - require.NoError(t, err) - require.Equal(t, request, data, "We should have the same request arriving on the server") - require.Equal(t, time.Now().Unix()/10, nowKernelTimestamp.Unix()/10, "kernel timestamps should be within 10s") - requireEqualNetAddrSockAddr(t, cconn.LocalAddr(), returnaddr) -} diff --git a/timestamp/timestamp_darwin.go b/timestamp/timestamp_notlinux.go similarity index 82% rename from timestamp/timestamp_darwin.go rename to timestamp/timestamp_notlinux.go index c84ec4c6..341a03f5 100644 --- a/timestamp/timestamp_darwin.go +++ b/timestamp/timestamp_notlinux.go @@ -1,3 +1,5 @@ +//go:build !linux + /* Copyright (c) Facebook, Inc. and its affiliates. @@ -88,35 +90,35 @@ func EnableTimestamps(ts Timestamp, connFd int, _ *net.Interface) error { // EnableRXQueueOverflow is not implemented for darwin func EnableRXQueueOverflow(_ int) error { - return fmt.Errorf("RX queue overflow is not supported on darwin") + return fmt.Errorf("RX queue overflow is not supported on this platform") } -// ReadTXtimestamp is not supported on darwin. +// ReadTXtimestamp is not supported on this platform. func ReadTXtimestamp(_ int) (time.Time, int, error) { - return time.Time{}, 0, errors.New("TX timestamping is not supported on darwin") + return time.Time{}, 0, errors.New("TX timestamping is not supported on this platform") } -// ReadTXtimestampBuf is not supported on darwin. +// ReadTXtimestampBuf is not supported on this platform. func ReadTXtimestampBuf(_ int, _, _ []byte) (time.Time, int, error) { - return time.Time{}, 0, errors.New("TX timestamping is unsupported on darwin") + return time.Time{}, 0, errors.New("TX timestamping is unsupported on this platform") } -// SeqIDSocketControlMessage is not supported on darwin. +// SeqIDSocketControlMessage is not supported on this platform. func SeqIDSocketControlMessage(_ uint32, _ []byte) { - // no-op on darwin + // no-op on this platform } -// ReadTimeStampSeqIDBuf is not supported on darwin. +// ReadTimeStampSeqIDBuf is not supported on this platform. func ReadTimeStampSeqIDBuf(_ int, _ []byte, _ uint32) (time.Time, int, error) { - return time.Time{}, 0, errors.New("timestamp sequence ID control messages are unsupported on darwin") + return time.Time{}, 0, errors.New("timestamp sequence ID control messages are unsupported on this platform") } -// EnableHWTimestamps is not supported on darwin. +// EnableHWTimestamps is not supported on this platform. func EnableHWTimestamps(_ int, _ *net.Interface) error { - return errors.New("hardware timestamping is not supported on darwin") + return errors.New("hardware timestamping is not supported on this platform") } -// EnableHWTimestampsRx is not supported on darwin. +// EnableHWTimestampsRx is not supported on this platform. func EnableHWTimestampsRx(_ int, _ *net.Interface) error { - return errors.New("hardware RX timestamping is not supported on darwin") + return errors.New("hardware RX timestamping is not supported on this platform") } diff --git a/timestamp/timestamp_darwin_test.go b/timestamp/timestamp_notlinux_test.go similarity index 99% rename from timestamp/timestamp_darwin_test.go rename to timestamp/timestamp_notlinux_test.go index dc4f15c6..50e1eb5a 100644 --- a/timestamp/timestamp_darwin_test.go +++ b/timestamp/timestamp_notlinux_test.go @@ -1,3 +1,5 @@ +//go:build !linux + /* Copyright (c) Facebook, Inc. and its affiliates.