Skip to content

Commit dabbd2f

Browse files
committed
Added support for options SO_TIMESTAMP, SO_TIMESTAMPNS and SO_TIMESTAMPING
1 parent 6923954 commit dabbd2f

File tree

5 files changed

+750
-4
lines changed

5 files changed

+750
-4
lines changed

src/lib.rs

+265
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,271 @@ impl RecvFlags {
383383
}
384384
}
385385

386+
/// Flags for network package timestamping configuration of a socket
387+
///
388+
/// On Unix flags are set at the `SOL_SOCKET` level and the `SO_TIMESTAMPING`
389+
/// option
390+
/// On Windows flags are set using `WSAIoctl` and the `SOI_TIMESTAMPING` option
391+
#[cfg(not(any(
392+
target_os = "dragonfly",
393+
target_os = "freebsd",
394+
target_os = "haiku",
395+
target_os = "illumos",
396+
target_os = "ios",
397+
target_os = "macos",
398+
target_os = "netbsd",
399+
target_os = "nto",
400+
target_os = "openbsd",
401+
target_os = "solaris",
402+
target_os = "tvos",
403+
target_os = "watchos",
404+
target_os = "redox",
405+
target_os = "fuchsia",
406+
target_os = "vita",
407+
target_os = "hurd",
408+
)))]
409+
#[cfg_attr(
410+
docsrs,
411+
doc(cfg(not(any(
412+
target_os = "dragonfly",
413+
target_os = "freebsd",
414+
target_os = "haiku",
415+
target_os = "illumos",
416+
target_os = "ios",
417+
target_os = "macos",
418+
target_os = "netbsd",
419+
target_os = "nto",
420+
target_os = "openbsd",
421+
target_os = "solaris",
422+
target_os = "tvos",
423+
target_os = "watchos",
424+
target_os = "redox",
425+
target_os = "fuchsia",
426+
target_os = "vita",
427+
target_os = "hurd",
428+
))))
429+
)]
430+
#[derive(Default, Debug, Copy, Clone, Eq, PartialEq)]
431+
pub struct TimestampingFlags(sys::c_uint);
432+
433+
#[cfg(not(any(
434+
target_os = "dragonfly",
435+
target_os = "freebsd",
436+
target_os = "haiku",
437+
target_os = "illumos",
438+
target_os = "ios",
439+
target_os = "macos",
440+
target_os = "netbsd",
441+
target_os = "nto",
442+
target_os = "openbsd",
443+
target_os = "solaris",
444+
target_os = "tvos",
445+
target_os = "watchos",
446+
target_os = "redox",
447+
target_os = "fuchsia",
448+
target_os = "vita",
449+
target_os = "hurd",
450+
)))]
451+
impl TimestampingFlags {
452+
/// Creates a new instance of `TimestampingFlags` with no flags set
453+
pub fn new() -> Self {
454+
Self(0)
455+
}
456+
457+
/// This flags controls if transmit timestamp reception should be enabled
458+
///
459+
/// This flag is only used for datagram-based sockets,
460+
/// not for stream sockets.
461+
///
462+
/// On Unix this corresponds to the `TIMESTAMPING_FLAG_RX` flag.
463+
#[cfg(target_os = "windows")]
464+
#[cfg_attr(docsrs, doc(cfg(target_os = "windows")))]
465+
pub fn set_rx(&mut self, active: bool) {
466+
self.set_flag(sys::TIMESTAMPING_FLAG_RX, active);
467+
}
468+
469+
/// This flags controls if receive timestamp reception should be enabled
470+
///
471+
/// This flag is only used for datagram-based sockets,
472+
/// not for stream sockets.
473+
///
474+
/// On Windows this corresponds to the `TIMESTAMPING_FLAG_TX` flag.
475+
#[cfg(target_os = "windows")]
476+
#[cfg_attr(docsrs, doc(cfg(target_os = "windows")))]
477+
pub fn set_tx(&mut self, active: bool) {
478+
self.set_flag(sys::TIMESTAMPING_FLAG_TX, active);
479+
}
480+
481+
/// This flags controls if rx timestamps should be generated by the network
482+
/// adapter
483+
///
484+
/// On Unix this corresponds to the `SOF_TIMESTAMPING_RX_HARDWARE` flag.
485+
#[cfg(not(target_os = "windows"))]
486+
#[cfg_attr(docsrs, doc(cfg(not(target_os = "windows"))))]
487+
pub fn set_rx_hardware_gen(&mut self, active: bool) {
488+
self.set_flag(sys::SOF_TIMESTAMPING_RX_HARDWARE, active)
489+
}
490+
491+
/// This flags controls if rx timestamps should be generated when a package
492+
/// enters the kernel. These timestamps are generated just after a device
493+
/// driver hands a packet to the kernel receive stack.
494+
///
495+
/// On Unix this corresponds to the `SOF_TIMESTAMPING_RX_SOFTWARE` flag.
496+
#[cfg(not(target_os = "windows"))]
497+
#[cfg_attr(docsrs, doc(cfg(not(target_os = "windows"))))]
498+
pub fn set_rx_software_gen(&mut self, active: bool) {
499+
self.set_flag(sys::SOF_TIMESTAMPING_RX_SOFTWARE, active)
500+
}
501+
502+
/// This flags controls if tx timestamps should be generated by the network
503+
/// adapter
504+
///
505+
/// On Unix this corresponds to the `SOF_TIMESTAMPING_TX_HARDWARE` flag.
506+
#[cfg(not(target_os = "windows"))]
507+
#[cfg_attr(docsrs, doc(cfg(not(target_os = "windows"))))]
508+
pub fn set_tx_hardware_gen(&mut self, active: bool) {
509+
self.set_flag(sys::SOF_TIMESTAMPING_TX_HARDWARE, active)
510+
}
511+
512+
/// This flags controls if tx timestamps should be generated when a package
513+
/// enters the kernel. These timestamps are generated just after a device
514+
/// driver hands a packet to the kernel receive stack.
515+
///
516+
/// On Unix this corresponds to the `SOF_TIMESTAMPING_TX_SOFTWARE` flag.
517+
#[cfg(not(target_os = "windows"))]
518+
#[cfg_attr(docsrs, doc(cfg(not(target_os = "windows"))))]
519+
pub fn set_tx_software_gen(&mut self, active: bool) {
520+
self.set_flag(sys::SOF_TIMESTAMPING_TX_SOFTWARE, active)
521+
}
522+
523+
/// This flags controls if tx timestamps should be generated prior to
524+
/// entering the packet scheduler.
525+
///
526+
/// On Unix this corresponds to the `SOF_TIMESTAMPING_TX_SCHED` flag.
527+
#[cfg(not(target_os = "windows"))]
528+
#[cfg_attr(docsrs, doc(cfg(not(target_os = "windows"))))]
529+
pub fn set_tx_sched_gen(&mut self, active: bool) {
530+
self.set_flag(sys::SOF_TIMESTAMPING_TX_SCHED, active)
531+
}
532+
533+
/// This flag controls if tx timestamps when all data in the send buffer
534+
/// has been acknowledged
535+
///
536+
/// This flag is only used for stream-based sockets,
537+
/// not for datagram sockets.
538+
///
539+
/// On Unix this corresponds to the `SOF_TIMESTAMPING_TX_ACK` flag.
540+
#[cfg(not(target_os = "windows"))]
541+
#[cfg_attr(docsrs, doc(cfg(not(target_os = "windows"))))]
542+
pub fn set_tx_ack_gen(&mut self, active: bool) {
543+
self.set_flag(sys::SOF_TIMESTAMPING_TX_ACK, active)
544+
}
545+
546+
/// This flag controls if any software generated timestamps should be
547+
/// reported when available.
548+
///
549+
/// On Unix this corresponds to the `SOF_TIMESTAMPING_SOFTWARE` flag.
550+
#[cfg(not(target_os = "windows"))]
551+
#[cfg_attr(docsrs, doc(cfg(not(target_os = "windows"))))]
552+
pub fn set_software_reporting(&mut self, active: bool) {
553+
self.set_flag(sys::SOF_TIMESTAMPING_SOFTWARE, active)
554+
}
555+
556+
/// This flag controls if any hardware generated timestamps such as
557+
/// SOF_TIMESTAMPING_TX_HARDWARE should be reported when available.
558+
///
559+
/// On Unix this corresponds to the `SOF_TIMESTAMPING_RAW_HARDWARE` flag.
560+
#[cfg(not(target_os = "windows"))]
561+
#[cfg_attr(docsrs, doc(cfg(not(target_os = "windows"))))]
562+
pub fn set_raw_hardware_reporting(&mut self, active: bool) {
563+
self.set_flag(sys::SOF_TIMESTAMPING_RAW_HARDWARE, active)
564+
}
565+
566+
/// This flag controls if a unique identifier should be generated for each
567+
/// packet. For datagram sockets, the counter increments with each sent
568+
/// packet. For stream sockets, it increments with every byte.
569+
///
570+
/// This option is only implemented for transmit timestamps.
571+
///
572+
/// On Unix this corresponds to the `SOF_TIMESTAMPING_OPT_ID` flag.
573+
#[cfg(not(target_os = "windows"))]
574+
#[cfg_attr(docsrs, doc(cfg(not(target_os = "windows"))))]
575+
pub fn set_opt_id(&mut self, active: bool) {
576+
self.set_flag(sys::SOF_TIMESTAMPING_OPT_ID, active)
577+
}
578+
579+
/// This flag controls if control messages should be supported for all
580+
/// timestamped packets. This option enables `recv()` `cmsg` support for
581+
/// IPv4 packets with transmit timestamps.
582+
///
583+
/// On Unix this corresponds to the `SOF_TIMESTAMPING_OPT_CMSG` flag.
584+
#[cfg(not(target_os = "windows"))]
585+
#[cfg_attr(docsrs, doc(cfg(not(target_os = "windows"))))]
586+
pub fn set_opt_cmsg(&mut self, active: bool) {
587+
self.set_flag(sys::SOF_TIMESTAMPING_OPT_CMSG, active)
588+
}
589+
590+
/// This flag controls if the timestamp should be returned as a `cmsg`
591+
/// alongside an empty packet, as opposed to alognside the original
592+
/// packet.
593+
///
594+
/// This option is only implemented for transmit timestamps.
595+
/// This option disables `SOF_TIMESTAMPING_OPT_CMSG` flag set by
596+
/// `set_opt_cmsg(bool)`
597+
///
598+
/// On Unix this corresponds to the `SOF_TIMESTAMPING_OPT_TSONLY` flag.
599+
#[cfg(not(target_os = "windows"))]
600+
#[cfg_attr(docsrs, doc(cfg(not(target_os = "windows"))))]
601+
pub fn set_opt_tsonly(&mut self, active: bool) {
602+
self.set_flag(sys::SOF_TIMESTAMPING_OPT_TSONLY, active)
603+
}
604+
605+
/// This flag controls if optional stats should be obtained along with the
606+
/// transmit timestamps.
607+
///
608+
/// This option must be used together with `SOF_TIMESTAMPING_OPT_TSONLY` set
609+
/// by `set_opt_tsonly(bool)`.
610+
///
611+
/// On Unix this corresponds to the `SOF_TIMESTAMPING_OPT_STATS` flag.
612+
#[cfg(not(target_os = "windows"))]
613+
#[cfg_attr(docsrs, doc(cfg(not(target_os = "windows"))))]
614+
pub fn set_opt_stats(&mut self, active: bool) {
615+
self.set_flag(sys::SOF_TIMESTAMPING_OPT_STATS, active)
616+
}
617+
618+
/// This flag enables the `SCM_TIMESTAMPING_PKTINFO` control message for
619+
/// incoming packets with hardware timestamps.
620+
///
621+
/// On Unix this corresponds to the `SOF_TIMESTAMPING_OPT_PKTINFO` flag.
622+
#[cfg(not(target_os = "windows"))]
623+
#[cfg_attr(docsrs, doc(cfg(not(target_os = "windows"))))]
624+
pub fn set_opt_pktinfo(&mut self, active: bool) {
625+
self.set_flag(sys::SOF_TIMESTAMPING_OPT_PKTINFO, active)
626+
}
627+
628+
/// This flag enables both hardware and software timestamps for outgoing
629+
/// packets when `SOF_TIMESTAMPING_TX_HARDWARE` and
630+
/// `SOF_TIMESTAMPING_TX_SOFTWARE` are enabled at the same time. If both
631+
/// timestamps are generated, two separate messages will be looped to the
632+
/// socket’s error queue, each containing just one timestamp.
633+
///
634+
/// On Unix this corresponds to the `SOF_TIMESTAMPING_OPT_TX_SWHW` flag.
635+
#[cfg(not(target_os = "windows"))]
636+
#[cfg_attr(docsrs, doc(cfg(not(target_os = "windows"))))]
637+
pub fn set_opt_tx_swhw(&mut self, active: bool) {
638+
self.set_flag(sys::SOF_TIMESTAMPING_OPT_TX_SWHW, active)
639+
}
640+
641+
#[inline(always)]
642+
fn set_flag(&mut self, flag: sys::c_uint, active: bool) {
643+
if active {
644+
self.0 |= flag;
645+
} else {
646+
self.0 &= !flag;
647+
}
648+
}
649+
}
650+
386651
/// A version of [`IoSliceMut`] that allows the buffer to be uninitialised.
387652
///
388653
/// [`IoSliceMut`]: std::io::IoSliceMut

0 commit comments

Comments
 (0)