ptp/ptp4u/server/config.go (96 lines of code) (raw):

/* 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" "time" "github.com/facebook/time/leapsectz" "github.com/facebook/time/ntp/shm" "github.com/facebook/time/phc" ptp "github.com/facebook/time/ptp/protocol" ) // Config is a server config structure type Config struct { DSCP int Interface string IP net.IP LogLevel string MaxSubDuration time.Duration MetricInterval time.Duration MinSubInterval time.Duration MonitoringPort int SHM bool Leapsectz bool TimestampType string UTCOffset time.Duration SendWorkers int RecvWorkers int QueueSize int DrainInterval time.Duration ClockClass uint ClockAccuracy uint clockIdentity ptp.ClockIdentity } func leapSanity(sec int) bool { if sec > 30 && sec < 50 { return true } return false } // SetUTCOffsetFromSHM reads SHM and if valid sets UTC offset func (c *Config) SetUTCOffsetFromSHM() error { phcTime, err := phc.Time(c.Interface, phc.MethodSyscallClockGettime) if err != nil { return err } shmTime, err := shm.Time() if err != nil { return err } // Safety check (http://leapsecond.com/java/gpsclock.htm): // SHM (NTP) time is always behind of the PHC (PTP) (as of 2021 by 37 seconds) // PHC (PTP) time is always ahead of the SHM (NTP) // SHM+30 <PHC< SHM+50 uo := phcTime.Sub(shmTime).Round(time.Second) if !leapSanity(int(uo.Seconds())) { return fmt.Errorf("shm (%s) and phc (%s) times are too far away: %s", shmTime, phcTime, uo) } c.UTCOffset = uo return nil } func (c *Config) SetUTCOffsetFromLeapsectz() error { var uo int32 = 10 latestLeap, err := leapsectz.Latest("") if err != nil { return err } uo += latestLeap.Nleap if !leapSanity(int(uo)) { return fmt.Errorf("UTC offset is unrealistic: %d seconds", uo) } c.UTCOffset = time.Duration(uo) * time.Second return nil } // IfaceHasIP checks if selected IP is on interface func (c *Config) IfaceHasIP() (bool, error) { ips, err := ifaceIPs(c.Interface) if err != nil { return false, err } for _, ip := range ips { if c.IP.Equal(ip) { return true, nil } } return false, nil } // ifaceIPs gets all IPs on the specified interface func ifaceIPs(iface string) ([]net.IP, error) { i, err := net.InterfaceByName(iface) if err != nil { return nil, err } addrs, err := i.Addrs() if err != nil { return nil, err } res := []net.IP{} for _, addr := range addrs { ip := addr.(*net.IPNet).IP res = append(res, ip) } res = append(res, net.IPv6zero) res = append(res, net.IPv4zero) return res, nil }