iris_core/config.rs
1//! Configuration options.
2//!
3//! While applications that use Iris are free to define their own command line arguments, Iris
4//! requires a separate configuration file that defines runtime options for CPU and memory usage,
5//! network interface(s), logging, protocol-specific items, and more. The path to the configuration
6//! file itself will typically be a command line argument passed to the application.
7//!
8//! Iris can run in either "online" mode (reading packets from a live network interface) or
9//! "offline" mode (reading packets from a capture file). See
10//! [configs](https://github.com/stanford-esrg/iris/tree/main/configs) for examples.
11
12use crate::lcore::{CoreId, SocketId};
13
14use std::fs;
15#[cfg(feature = "prometheus")]
16use std::net::{IpAddr, Ipv4Addr};
17use std::path::Path;
18
19use serde::{Deserialize, Serialize};
20
21/// Loads a configuration file from `path`.
22pub fn load_config<P: AsRef<Path>>(path: P) -> RuntimeConfig {
23 let config_str = fs::read_to_string(path).expect("ERROR: File read failed");
24 let config: RuntimeConfig = toml::from_str(&config_str).expect("Invalid config file");
25
26 // error check config
27 if config.online.is_some() == config.offline.is_some() {
28 log::error!(
29 "Configure either live ports or offline analysis: {:#?}",
30 config
31 );
32 panic!();
33 }
34 config
35}
36
37/// Loads a default configuration file.
38///
39/// For demonstration purposes only, not configured for performance. The default configuration
40/// assumes Iris is being run from the crate root in offline mode:
41/// ```toml
42/// main_core = 0
43///
44/// [mempool]
45/// capacity = 8192
46///
47/// [offline]
48/// pcap = "./traces/small_flows.pcap"
49/// mtu = 9702
50///
51/// [conntrack]
52/// max_connections = 100_000
53/// ```
54pub fn default_config() -> RuntimeConfig {
55 RuntimeConfig::default()
56}
57
58/* --------------------------------------------------------------------------------- */
59
60/// Runtime configuration options.
61#[derive(Deserialize, Serialize, Debug, Clone)]
62pub struct RuntimeConfig {
63 /// Main core identifier. Initializes and manages packet processing cores and logging, but does
64 /// not process packets itself.
65 pub main_core: u32,
66
67 /// Sets the number of memory channels to use.
68 ///
69 /// This controls the spread layout used by the memory allocator and is mainly for performance
70 /// optimization. Can be configured up to be the number of channels per CPU socket if the
71 /// platform supports multiple memory channels. Defaults to `1`.
72 #[serde(default = "default_nb_memory_channels")]
73 pub nb_memory_channels: usize,
74
75 /// Suppress DPDK runtime logging and telemetry output. Defaults to `true`.
76 #[serde(default = "default_suppress_dpdk_output")]
77 pub suppress_dpdk_output: bool,
78
79 /// Per-mempool settings.
80 pub mempool: MempoolConfig,
81
82 /// Online mode settings. Either `online` or `offline` must be specified.
83 #[serde(default = "default_online")]
84 pub online: Option<OnlineConfig>,
85
86 /// Offline mode settings. Either `online` or `offline` must be specified.
87 #[serde(default = "default_offline")]
88 pub offline: Option<OfflineConfig>,
89
90 /// Connection tracking settings.
91 pub conntrack: ConnTrackConfig,
92
93 #[doc(hidden)]
94 /// Runtime filter for testing purposes.
95 #[serde(default = "default_filter")]
96 pub filter: Option<String>,
97}
98
99impl RuntimeConfig {
100 /// Returns a list of core IDs assigned to the runtime.
101 pub fn get_all_core_ids(&self) -> Vec<CoreId> {
102 let mut cores = vec![CoreId(self.main_core)];
103 if let Some(online) = &self.online {
104 for port in online.ports.iter() {
105 cores.extend(port.cores.iter().map(|c| CoreId(*c)));
106 if let Some(sink) = &port.sink {
107 cores.push(CoreId(sink.core));
108 }
109 }
110 }
111 cores.sort();
112 cores.dedup();
113 cores
114 }
115
116 pub fn get_all_rx_core_ids(&self) -> Vec<CoreId> {
117 let mut cores = vec![];
118 if let Some(online) = &self.online {
119 for port in online.ports.iter() {
120 cores.extend(port.cores.iter().map(|c| CoreId(*c)));
121 }
122 } else {
123 cores.push(CoreId(self.main_core));
124 }
125 cores.sort();
126 cores.dedup();
127 cores
128 }
129
130 /// Returns a list of socket IDs in use.
131 pub(crate) fn get_all_socket_ids(&self) -> Vec<SocketId> {
132 let mut sockets = vec![];
133 for core_id in self.get_all_core_ids() {
134 sockets.push(core_id.socket_id());
135 }
136 sockets.sort();
137 sockets.dedup();
138 sockets
139 }
140
141 /// Returns DPDK EAL parameters.
142 #[allow(clippy::vec_init_then_push)]
143 pub(crate) fn get_eal_params(&self) -> Vec<String> {
144 let mut eal_params = vec![];
145
146 eal_params.push("--main-lcore".to_owned());
147 eal_params.push(self.main_core.to_string());
148
149 eal_params.push("-l".to_owned());
150 let core_list: Vec<String> = self
151 .get_all_core_ids()
152 .iter()
153 .map(|c| c.raw().to_string())
154 .collect();
155 eal_params.push(core_list.join(","));
156
157 if let Some(online) = &self.online {
158 for supl_arg in online.dpdk_supl_args.iter() {
159 eal_params.push(supl_arg.to_string())
160 }
161 for port in online.ports.iter() {
162 eal_params.push("-a".to_owned());
163 eal_params.push(port.device.to_string());
164 }
165 }
166
167 if let Some(offline) = &self.offline {
168 for supl_arg in offline.dpdk_supl_args.iter() {
169 eal_params.push(supl_arg.to_string())
170 }
171 }
172
173 eal_params.push("-n".to_owned());
174 eal_params.push(self.nb_memory_channels.to_string());
175
176 if self.suppress_dpdk_output {
177 eal_params.push("--log-level=6".to_owned());
178 eal_params.push("--no-telemetry".to_owned());
179 }
180
181 eal_params
182 }
183}
184
185fn default_nb_memory_channels() -> usize {
186 1
187}
188
189fn default_suppress_dpdk_output() -> bool {
190 true
191}
192
193fn default_online() -> Option<OnlineConfig> {
194 None
195}
196
197fn default_offline() -> Option<OfflineConfig> {
198 None
199}
200
201fn default_filter() -> Option<String> {
202 None
203}
204
205impl Default for RuntimeConfig {
206 fn default() -> Self {
207 RuntimeConfig {
208 main_core: 0,
209 nb_memory_channels: 1,
210 suppress_dpdk_output: true,
211 mempool: MempoolConfig {
212 capacity: 8192,
213 cache_size: 512,
214 },
215 online: None,
216 offline: Some(OfflineConfig {
217 mtu: 9702,
218 // assumes Iris is being run from crate root
219 pcap: "./traces/small_flows.pcap".to_string(),
220 dpdk_supl_args: Vec::new(),
221 }),
222 conntrack: ConnTrackConfig {
223 max_connections: 100_000,
224 max_out_of_order: 100,
225 timeout_resolution: 100,
226 udp_inactivity_timeout: 60_000,
227 tcp_inactivity_timeout: 300_000,
228 tcp_reassembly_timeout: 300_000,
229 tcp_establish_timeout: 5000,
230 init_synack: false,
231 init_fin: false,
232 init_rst: false,
233 init_data: false,
234 },
235 filter: None,
236 }
237 }
238}
239
240/* --------------------------------------------------------------------------------- */
241
242/// Memory pool options.
243///
244/// Iris manages packet buffer memory using DPDK's pool-based memory allocator. This takes
245/// advantage of built-in DPDK huge page support, NUMA affinity, and access to DMA addresses. See
246/// [Memory in DPDK](https://www.dpdk.org/blog/2019/08/21/memory-in-dpdk-part-1-general-concepts/)
247/// for more details.
248///
249/// ## Example
250/// ```toml
251/// [mempool]
252/// capacity = 1_048_576
253/// cache_size = 512
254/// ```
255#[derive(Deserialize, Serialize, Debug, Clone)]
256pub struct MempoolConfig {
257 /// Number of mbufs allocated per mempool. The maximum value that can be set will depend on
258 /// the available memory (number of hugepages allocated) and the MTU. Defaults to `65536`.
259 #[serde(default = "default_capacity")]
260 pub capacity: usize,
261
262 /// The size of the per-core object cache. It is recommended that `cache_size` evenly divides
263 /// `capacity`. Defaults to `512`.
264 #[serde(default = "default_cache_size")]
265 pub cache_size: usize,
266}
267
268fn default_capacity() -> usize {
269 65536
270}
271
272fn default_cache_size() -> usize {
273 512
274}
275
276/* --------------------------------------------------------------------------------- */
277
278/// Live traffic analysis options.
279///
280/// Online mode performs traffic analysis on a live network interface. Either
281/// [OnlineConfig] or [OfflineConfig] must be specified, but not both.
282///
283/// ## Example
284/// ```toml
285/// [online]
286/// duration = 30
287/// nb_rxd = 32768
288/// promiscuous = true
289/// mtu = 1500
290/// hardware_assist = true
291/// dpdk_supl_args = []
292///
293/// [online.monitor.display]
294/// throughput = true
295/// mempool_usage = true
296///
297/// [online.monitor.log]
298/// directory = "./log"
299/// interval = 1000
300///
301/// [[online.ports]]
302/// device = "0000:3b:00.0"
303/// cores = [1,2,3,4]
304///
305/// [[online.ports]]
306/// device = "0000:3b:00.1"
307/// cores = [5,6,7,8]
308/// ```
309#[derive(Deserialize, Serialize, Debug, Clone)]
310pub struct OnlineConfig {
311 /// If set, the applicaton will stop after `duration` seconds. Defaults to `None`.
312 #[serde(default = "default_duration")]
313 pub duration: Option<u64>,
314
315 /// Whether promiscuous mode is enabled for all ports. Defaults to `true`.
316 #[serde(default = "default_promiscuous")]
317 pub promiscuous: bool,
318
319 /// The number of RX descriptors per receive queue. Defaults to `4096`.
320 ///
321 /// Receive queues are polled for packets using a run-to-completion model. Deeper queues will be
322 /// more tolerant of processing delays at the cost of higher memory usage and hugepage
323 /// reservation.
324 #[serde(default = "default_portqueue_nb_rxd")]
325 pub nb_rxd: usize,
326
327 /// Maximum transmission unit (in bytes) allowed for ingress packets. Defaults to `1500`.
328 ///
329 /// To capture jumbo frames, set this value higher (e.g., `9702`).
330 #[serde(default = "default_mtu")]
331 pub mtu: usize,
332
333 /// If set, will attempt to offload parts of the filter to the NIC, depending on its hardware
334 /// filtering support. Defaults to `true`.
335 #[serde(default = "default_hardware_assist")]
336 pub hardware_assist: bool,
337
338 /// If set, will pass supplementary arguments to DPDK EAL (see DPDK
339 /// configuration). For instance `--no-huge`.
340 /// Defaults to empty string.
341 #[serde(default = "default_dpdk_supl_args")]
342 pub dpdk_supl_args: Vec<String>,
343
344 /// Live performance monitoring. Defaults to `None`.
345 #[serde(default = "default_monitor")]
346 pub monitor: Option<MonitorConfig>,
347
348 /// Prometheus metrics exporter server. Defaults to `None`.
349 #[serde(default = "default_prometheus")]
350 #[cfg(feature = "prometheus")]
351 pub prometheus: Option<PrometheusConfig>,
352
353 /// List of network interfaces to read from.
354 pub ports: Vec<PortMap>,
355}
356
357fn default_duration() -> Option<u64> {
358 None
359}
360
361fn default_hardware_assist() -> bool {
362 true
363}
364
365fn default_dpdk_supl_args() -> Vec<String> {
366 Vec::new()
367}
368
369fn default_promiscuous() -> bool {
370 true
371}
372
373fn default_portqueue_nb_rxd() -> usize {
374 4096
375}
376
377fn default_mtu() -> usize {
378 1500
379}
380
381fn default_monitor() -> Option<MonitorConfig> {
382 None
383}
384
385#[cfg(feature = "prometheus")]
386fn default_prometheus() -> Option<PrometheusConfig> {
387 None
388}
389
390/* --------------------------------------------------------------------------------- */
391
392/// Sink core options.
393///
394/// A "sink" core is a utility core whose sole purpose is to drop received traffic. This is useful
395/// for connection sampling, as entire 4-tuples can be discarded by redirecting them to the sink
396/// core.
397///
398/// ## Remarks
399/// Adding a sink core prevents ethtool counters from classifying intentionally discarded packets as
400/// packet loss. However, it can be quite wasteful of system resources, as it requires configuring
401/// one additional core per interface and thrashes the cache.
402///
403/// ## Example
404/// ```toml
405/// [online.ports.sink]
406/// core = 9
407/// nb_buckets = 384 # drops 25% of 4-tuples
408/// ```
409#[derive(Deserialize, Serialize, Debug, Clone)]
410pub struct SinkConfig {
411 /// Sink core identifier.
412 pub core: u32,
413
414 /// Number of RSS redirection table buckets to use for receive queues. Defaults to `512`, which
415 /// indicates no sampling.
416 ///
417 /// ## Remarks
418 /// Connection sampling is implemented by only polling from a fraction of the available RSS
419 /// redirection buckets. `nb_buckets` must range from the number of cores polling the port (call
420 /// this `n`) to `512`, which is the maximum number of buckets in the RSS redirection table. It
421 /// is recommended that `nb_buckets` be a multiple of `n` for better load balancing. For
422 /// example, setting `nb_buckets = 256` would drop 50% of connections.
423 #[serde(default = "default_nb_buckets")]
424 pub nb_buckets: usize,
425}
426
427fn default_nb_buckets() -> usize {
428 512
429}
430
431/* --------------------------------------------------------------------------------- */
432
433/// Network interface options.
434///
435/// ## Example
436/// ```toml
437/// [[online.ports]]
438/// device = "0000:3b:00.0"
439/// cores = [1,2,3,4,5,6,7,8]
440/// ```
441#[derive(Deserialize, Serialize, Debug, Clone)]
442pub struct PortMap {
443 /// PCI address of interface.
444 pub device: String,
445
446 /// List of packet processing cores used to poll the interface.
447 ///
448 /// ## Remarks
449 /// For performance, it is recommended that the processing cores reside on the same NUMA node as
450 /// the PCI device.
451 pub cores: Vec<u32>,
452
453 /// Sink core configuration. Defaults to `None`.
454 #[serde(default = "default_sink")]
455 pub sink: Option<SinkConfig>,
456}
457
458fn default_sink() -> Option<SinkConfig> {
459 None
460}
461
462/* --------------------------------------------------------------------------------- */
463
464/// Statistics logging and live monitoring operations.
465///
466/// ## Example
467/// ```toml
468/// [online.monitor.display]
469/// throughput = true
470/// mempool_usage = true
471///
472/// [online.monitor.log]
473/// directory = "./log"
474/// interval = 1000
475/// ```
476#[derive(Deserialize, Serialize, Debug, Clone)]
477pub struct MonitorConfig {
478 /// Live display configuration. Defaults to `None` (no output).
479 #[serde(default = "default_display")]
480 pub display: Option<DisplayConfig>,
481
482 /// Logging configuration. Defaults to `None` (no logs).
483 #[serde(default = "default_log")]
484 pub log: Option<LogConfig>,
485}
486
487fn default_display() -> Option<DisplayConfig> {
488 None
489}
490
491fn default_log() -> Option<LogConfig> {
492 None
493}
494
495/// Statistics logging and live monitoring operations.
496///
497/// ## Example
498/// ```toml
499/// [online.monitor.display]
500/// throughput = true
501/// mempool_usage = true
502///
503/// [online.monitor.log]
504/// directory = "./log"
505/// interval = 1000
506/// ```
507#[derive(Deserialize, Serialize, Debug, Clone, Copy)]
508#[cfg(feature = "prometheus")]
509pub struct PrometheusConfig {
510 /// Listen port for Prometheus metrics.
511 pub port: u16,
512
513 /// Listen bind address for Prometheus metrics. Defaults to `127.0.0.1`.
514 #[serde(default = "default_prometheus_ip")]
515 pub ip: IpAddr,
516}
517
518#[cfg(feature = "prometheus")]
519fn default_prometheus_ip() -> IpAddr {
520 IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1))
521}
522
523/* --------------------------------------------------------------------------------- */
524
525/// Live statistics display options.
526///
527/// If enabled, live statistics will be displayed to stdout once per second.
528///
529/// ## Example
530/// ```toml
531/// [online.monitor.display]
532/// throughput = true
533/// mempool_usage = true
534/// ```
535#[derive(Deserialize, Serialize, Debug, Clone)]
536pub struct DisplayConfig {
537 /// Display live throughputs. Defaults to `true`.
538 #[serde(default = "default_display_throughput")]
539 pub throughput: bool,
540
541 /// Display live mempool usage. Defaults to `true`.
542 #[serde(default = "default_display_mempool_usage")]
543 pub mempool_usage: bool,
544
545 /// List of live port statistics to display.
546 ///
547 /// ## Remarks
548 /// Available options vary depending on the NIC driver and its supported counters. A port
549 /// statistic will be displayed if it contains (as a substring) any item in the `port_stats`
550 /// list. To display all available port statistics, set this value to a list containing the
551 /// empty string (`port_stats = [""]`). Defaults to displaying no statistics (`port_stats =
552 /// []`).
553 #[serde(default = "default_display_port_stats")]
554 pub port_stats: Vec<String>,
555}
556
557fn default_display_throughput() -> bool {
558 true
559}
560
561fn default_display_mempool_usage() -> bool {
562 true
563}
564
565fn default_display_port_stats() -> Vec<String> {
566 vec![]
567}
568
569/* --------------------------------------------------------------------------------- */
570
571/// Logging options.
572///
573/// ## Example
574/// ```toml
575/// [online.monitor.log]
576/// directory = "./log"
577/// interval = 1000
578/// port_stats = ["rx"] # only log stats with "rx" in its name
579/// ```
580#[derive(Deserialize, Serialize, Debug, Clone)]
581pub struct LogConfig {
582 /// Log directory path. If logging is enabled, Iris will write logs to a timestamped folder
583 /// inside `directory`. Defaults to `"./log"`.
584 #[serde(default = "default_log_directory")]
585 pub directory: String,
586
587 /// How often to log port statistics (in milliseconds). Defaults to `1000`.
588 #[serde(default = "default_log_interval")]
589 pub interval: u64,
590
591 /// List of port statistics to log.
592 ///
593 /// Available options vary depending on the NIC driver and its supported counters. A port
594 /// statistic will be logged if it contains (as a substring) any item in the `port_stats` list.
595 /// To log all available port statistics, set this value to a list containing the empty string
596 /// (`port_stats = [""]`). Defaults to logging receive statistics (`port_stats = ["rx"]`).
597 #[serde(default = "default_log_port_stats")]
598 pub port_stats: Vec<String>,
599}
600
601fn default_log_directory() -> String {
602 "./log/".to_string()
603}
604
605fn default_log_interval() -> u64 {
606 1000
607}
608
609fn default_log_port_stats() -> Vec<String> {
610 vec!["rx".to_string()]
611}
612
613/* --------------------------------------------------------------------------------- */
614
615/// Offline traffic analysis options.
616///
617/// Offline mode runs using a single core and performs offline analysis of already captured pcap
618/// files. Either [OnlineConfig] or [OfflineConfig] must be specified,
619/// but not both. This mode is primarily intended for functional testing.
620///
621/// ## Example
622/// ```toml
623/// [offline]
624/// pcap = "sample_pcaps/smallFlows.pcap"
625/// mtu = 9702
626/// ```
627#[derive(Deserialize, Serialize, Debug, Clone)]
628pub struct OfflineConfig {
629 /// Path to packet capture (pcap) file.
630 pub pcap: String,
631
632 /// Maximum frame size, equivalent to MTU on a live interface. Defaults to `1500`.
633 ///
634 /// To include jumbo frames, set this value higher (e.g., `9702`).
635 #[serde(default = "default_mtu")]
636 pub mtu: usize,
637
638 /// If set, will pass supplementary arguments to DPDK EAL (see DPDK configuration).
639 /// Defaults to empty.
640 ///
641 /// Useful for running a trace without root: `["--no-huge", "--no-pci", "-m", "6144"]`
642 /// takes memory from the regular heap instead of hugepages (which are typically
643 /// root-only) and skips NIC probing, neither of which offline mode needs. Expect a
644 /// performance hit; this is for testing, not measurement.
645 #[serde(default = "default_dpdk_supl_args")]
646 pub dpdk_supl_args: Vec<String>,
647}
648
649/* --------------------------------------------------------------------------------- */
650
651/// Connection tracking options.
652///
653/// These options can be used to tune for resource usage vs. accuracy depending on expected network
654/// characteristics.
655///
656/// ## Example
657/// ```toml
658/// [conntrack]
659/// max_connections = 10_000_000
660/// max_out_of_order = 100
661/// timeout_resolution = 100
662/// udp_inactivity_timeout = 60_000
663/// tcp_inactivity_timeout = 300_000
664/// tcp_establish_timeout = 5000
665/// ```
666#[derive(Deserialize, Serialize, Debug, Clone)]
667pub struct ConnTrackConfig {
668 /// Maximum number of connections that can be tracked simultaneously per-core. Defaults to
669 /// `10_000_000`.
670 #[serde(default = "default_max_connections")]
671 pub max_connections: usize,
672
673 /// Maximum number of out-of-order packets allowed per TCP connection before it is force
674 /// expired. Defaults to `100`.
675 #[serde(default = "default_max_out_of_order")]
676 pub max_out_of_order: usize,
677
678 /// Frequency to check for inactive streams (in milliseconds). Defaults to `1000` (1 second).
679 #[serde(default = "default_timeout_resolution")]
680 pub timeout_resolution: usize,
681
682 /// A UDP connection can be inactive for up to this amount of time (in milliseconds) before it
683 /// is force expired. Defaults to `60_000` (1 minute).
684 #[serde(default = "default_udp_inactivity_timeout")]
685 pub udp_inactivity_timeout: usize,
686
687 /// A TCP connection can be inactive for up to this amount of time (in milliseconds) before it
688 /// is force expired. Defaults to `300_000` (5 minutes).
689 #[serde(default = "default_tcp_inactivity_timeout")]
690 pub tcp_inactivity_timeout: usize,
691
692 /// Override the default TCP connection inactivity timeout with this value (in milliseconds)
693 /// if there are unfilled sequence number gaps.
694 ///
695 /// Defaults to `tcp_inactivity_timeout`. This is used to prevent memory exhaustion
696 /// on networks where there may be loss between the ground truth TCP connection (guaranteed retransmissions)
697 /// and the monitoring vantage point (retransmissions not guaranteed).
698 #[serde(default = "default_tcp_inactivity_timeout")]
699 pub tcp_reassembly_timeout: usize,
700
701 /// Inactivity time between the first and second packet of a TCP connection before it is force
702 /// expired (in milliseconds).
703 ///
704 /// This approximates connections that remain inactive in either the `SYN-SENT` or
705 /// `SYN-RECEIVED` state without progressing. It is used to prevent memory exhaustion due to SYN
706 /// scans and SYN floods. Defaults to `5000` (5 seconds).
707 #[serde(default = "default_tcp_establish_timeout")]
708 pub tcp_establish_timeout: usize,
709
710 #[doc(hidden)]
711 /// Whether to track TCP connections where the first observed packet is a SYN/ACK. Defaults to
712 /// `false`.
713 #[serde(default = "default_init_synack")]
714 pub init_synack: bool,
715
716 #[doc(hidden)]
717 /// Whether to track TCP connections where the first observed packet is a FIN. Defaults to
718 /// `false`.
719 #[serde(default = "default_init_fin")]
720 pub init_fin: bool,
721
722 #[doc(hidden)]
723 /// Whether to track TCP connections where the first observed packet is a RST. Defaults to
724 /// `false`.
725 #[serde(default = "default_init_rst")]
726 pub init_rst: bool,
727
728 #[doc(hidden)]
729 /// Whether to track TCP connections where the first observed packet is a DATA. Defaults to
730 /// `false`.
731 #[serde(default = "default_init_data")]
732 pub init_data: bool,
733}
734
735fn default_max_connections() -> usize {
736 10_000_000
737}
738
739fn default_max_out_of_order() -> usize {
740 100
741}
742
743fn default_timeout_resolution() -> usize {
744 1000
745}
746
747fn default_udp_inactivity_timeout() -> usize {
748 60_000
749}
750
751fn default_tcp_inactivity_timeout() -> usize {
752 300_000
753}
754
755fn default_tcp_establish_timeout() -> usize {
756 5000
757}
758
759fn default_init_synack() -> bool {
760 false
761}
762
763fn default_init_fin() -> bool {
764 false
765}
766
767fn default_init_rst() -> bool {
768 false
769}
770
771fn default_init_data() -> bool {
772 false
773}