in ptp/ptp4u/server/worker.go [67:141]
func (s *sendWorker) listen() (eventFD, generalFD int, err error) {
// socket domain differs depending whether we are listening on ipv4 or ipv6
domain := unix.AF_INET6
if s.config.IP.To4() != nil {
domain = unix.AF_INET
}
// set up event connection
eventFD, err = unix.Socket(domain, unix.SOCK_DGRAM, unix.IPPROTO_UDP)
if err != nil {
return -1, -1, fmt.Errorf("creating event socket error: %w", err)
}
sockAddrAnyPort := timestamp.IPToSockaddr(s.config.IP, 0)
// set SO_REUSEPORT so we can potentially trace network path from same source port.
// needs to be set before we bind to a port.
if err = unix.SetsockoptInt(eventFD, unix.SOL_SOCKET, unix.SO_REUSEPORT, 1); err != nil {
return -1, -1, fmt.Errorf("failed to set SO_REUSEPORT on event socket: %w", err)
}
// bind to any ephemeral port
if err := unix.Bind(eventFD, sockAddrAnyPort); err != nil {
return -1, -1, fmt.Errorf("unable to bind event socket connection: %w", err)
}
// get local port we'll send packets from
localSockAddr, err := unix.Getsockname(eventFD)
if err != nil {
return -1, -1, fmt.Errorf("unable to find local ip: %w", err)
}
switch v := localSockAddr.(type) {
case *unix.SockaddrInet4:
log.Infof("Started worker#%d event on [%v]:%d", s.id, net.IP(v.Addr[:]), v.Port)
case *unix.SockaddrInet6:
log.Infof("Started worker#%d event on [%v]:%d", s.id, net.IP(v.Addr[:]), v.Port)
default:
log.Errorf("Unexpected local addr type %T", v)
}
if err = enableDSCP(eventFD, s.config.IP, s.config.DSCP); err != nil {
return -1, -1, fmt.Errorf("setting DSCP on event socket: %w", err)
}
// Syncs sent from event port, so need to turn on timestamping here
switch s.config.TimestampType {
case timestamp.HWTIMESTAMP:
if err := timestamp.EnableHWTimestamps(eventFD, s.config.Interface); err != nil {
return -1, -1, fmt.Errorf("failed to enable RX hardware timestamps: %w", err)
}
case timestamp.SWTIMESTAMP:
if err := timestamp.EnableSWTimestamps(eventFD); err != nil {
return -1, -1, fmt.Errorf("unable to enable RX software timestamps: %w", err)
}
default:
return -1, -1, fmt.Errorf("unrecognized timestamp type: %s", s.config.TimestampType)
}
// set up general connection
generalFD, err = unix.Socket(domain, unix.SOCK_DGRAM, unix.IPPROTO_UDP)
if err != nil {
return -1, -1, fmt.Errorf("creating general socket error: %w", err)
}
// set SO_REUSEPORT so we can potentially trace network path from same source port.
// needs to be set before we bind to a port.
if err = unix.SetsockoptInt(generalFD, unix.SOL_SOCKET, unix.SO_REUSEPORT, 1); err != nil {
return -1, -1, fmt.Errorf("failed to set SO_REUSEPORT on general socket: %w", err)
}
// bind to any ephemeral port
if err := unix.Bind(generalFD, sockAddrAnyPort); err != nil {
return -1, -1, fmt.Errorf("binding event socket connection: %w", err)
}
// enable DSCP
if err = enableDSCP(generalFD, s.config.IP, s.config.DSCP); err != nil {
return -1, -1, fmt.Errorf("setting DSCP on general socket: %w", err)
}
return
}