1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
//! Implementation of network connectivity checks.
//!
//! This module contains the actual check implementations for different protocols:
//! - HTTP checks via HEAD requests
//! - ICMP checks via ping
//! - DNS checks (planned)
//!
//! All check functions follow the pattern:
//! - Take a target IP address
//! - Perform the check with timeout
//! - Return latency on success or error on failure
//!
//! # Feature Flags
//!
//! Check types can be enabled/disabled via feature flags:
//! - `http` - Enable HTTP checks
//! - `ping` - Enable ICMP checks
//!
//! # Example
//!
//! ```rust
//! # #[cfg(feature = "http")] {// only works with that feature
//! use netpulse::checks;
//! use std::net::IpAddr;
//!
//! let addr: IpAddr = "1.1.1.1".parse().unwrap();
//!
//! // Perform HTTP check
//! if let Ok(latency) = checks::check_http(addr) {
//! println!("HTTP latency: {}ms", latency);
//! }
//! # }
//! ```
use IpAddr;
use crateCheckError;
use crateTIMEOUT;
/// Performs an ICMP ping check to the specified IP address.
///
/// Uses raw sockets to send ICMP echo request and measure round-trip time.
/// This function requires the `ping` feature to be enabled.
///
/// # Required Capabilities
///
/// This function requires the `CAP_NET_RAW` capability to create and use raw sockets for ICMP.
/// Without this capability, the function will fail with a permission error.
///
/// **Note**: When running as a daemon, this capability is typically lost when dropping privileges
/// from root to the daemon user. As a result, ICMP checks may not work in daemon mode.
///
/// # Arguments
///
/// * `remote` - Target IP address to ping (IPv4 or IPv6)
///
/// # Returns
///
/// * `Ok(u16)` - Round-trip time in milliseconds if ping succeeds
/// * `Err(CheckError)` - If ping fails (timeout, network error, etc)
///
/// # Errors
///
/// Returns `CheckError` if:
/// - Raw socket creation fails (typically due to missing CAP_NET_RAW)
/// - Ping times out ([`TIMEOUT`])
/// - Network is unreachable
/// - Permission denied
///
/// # Examples
///
/// ```rust,no_run
/// use std::net::IpAddr;
/// use netpulse::checks::just_fucking_ping;
///
/// let addr: IpAddr = "1.1.1.1".parse().unwrap();
/// match just_fucking_ping(addr) {
/// Ok(latency) => println!("Ping latency: {}ms", latency),
/// Err(e) => eprintln!("Ping failed: {}", e),
/// }
/// ```
/// Performs an HTTP HEAD request to check connectivity to the specified IP address.
///
/// Makes an HTTP/HTTPS HEAD request to measure response time. Uses curl under the hood
/// and requires the `http` feature to be enabled.
///
/// # Arguments
///
/// * `remote` - Target IP address for HTTP check (IPv4 or IPv6)
///
/// # Returns
///
/// * `Ok(u16)` - Round-trip time in milliseconds if request succeeds
/// * `Err(CheckError)` - If request fails (timeout, connection refused, etc)
///
/// # Errors
///
/// Returns `CheckError` if:
/// - DNS resolution fails
/// - Connection fails or is refused
/// - Request times out ([`TIMEOUT`])
/// - HTTP response indicates error
/// - URL construction fails
///
/// # IPv6 Handling
///
/// When checking IPv6 addresses, the address is wrapped in square brackets
/// to form a valid URL (e.g. `http://[2606:4700:4700::1111]`).
///
/// # Examples
///
/// ```rust
/// use std::net::IpAddr;
/// use netpulse::checks::check_http;
///
/// let addr: IpAddr = "1.1.1.1".parse().unwrap();
/// match check_http(addr) {
/// Ok(latency) => println!("HTTP latency: {}ms", latency),
/// Err(e) => eprintln!("HTTP check failed: {}", e),
/// }
/// ```