967eb5b76fd7813c5651bda110c3326aa1ca5b9d
4 time
::{self, Duration
},
9 message
::header
::ContentType
, transport
::smtp
::authentication
::Credentials
, Message
,
10 SmtpTransport
, Transport
,
12 use rand
::{rngs
::ThreadRng
, Rng
};
14 use crate::config
::Config
;
18 const FILE_CONF
: &str = "config.ron";
19 const PING_PERIOD
: Duration
= Duration
::from_secs(5); // 5 s.
20 const EMAIL_RESEND_PERIOD
: Duration
= Duration
::from_secs(2 * 60 * 60); // 2 h.
21 const STATE_PRINT_PERIOD
: Duration
= Duration
::from_secs(15 * 60); // 15 min.
23 fn main() -> Result
<()> {
24 println!("Staking Watchdog Watchdog");
26 let config
= Config
::read(FILE_CONF
)?
;
29 "Configuration: {:?}",
31 smtp_password
: "*****".to_string(),
36 let mut time_last_email_send
= time
::Instant
::now() - EMAIL_RESEND_PERIOD
;
37 let mut time_last_state_printed
= time
::Instant
::now() - STATE_PRINT_PERIOD
;
38 let mut error_state
= false;
40 let mut rng
= rand
::thread_rng();
42 let mut number_of_pings
= 0;
43 let mut total_ping_duration
= Duration
::default();
45 let socket
= UdpSocket
::bind("0.0.0.0:0").unwrap();
46 socket
.connect("192.168.2.102:8739").unwrap();
48 .set_read_timeout(Some(Duration
::from_secs(5)))
51 .set_write_timeout(Some(Duration
::from_secs(5)))
55 let time_beginning_loop
= time
::Instant
::now();
57 match ping(&socket
, &mut rng
) {
59 total_ping_duration
+= t
;
64 println!("End of erroneous state");
67 if time
::Instant
::now() - time_last_state_printed
>= STATE_PRINT_PERIOD
{
69 "No error detected. Mean of ping time: {} μs",
70 total_ping_duration
.as_micros() / number_of_pings
72 total_ping_duration
= Duration
::default();
74 time_last_state_printed
= time
::Instant
::now();
79 println!("Error: {:?}", error
);
80 if time
::Instant
::now() - time_last_email_send
>= EMAIL_RESEND_PERIOD
{
82 println!("Sending email...");
85 &format!("Error: {:?}", error
),
87 &config
.smtp_password
,
89 Err(email_error
) => println!("Error sending email: {:?}", email_error
),
91 println!("Email successfully sent");
92 time_last_email_send
= time
::Instant
::now();
99 let elapsed
= time
::Instant
::now() - time_beginning_loop
;
101 if elapsed
< PING_PERIOD
{
102 let to_wait
= PING_PERIOD
- elapsed
;
103 thread
::sleep(to_wait
);
110 SocketError(std
::io
::Error
),
111 WrongMessageReceived(String
),
114 fn ping(socket
: &UdpSocket
, rng
: &mut ThreadRng
) -> std
::result
::Result
<Duration
, PingError
> {
115 let number
: u64 = rng
.gen();
116 let mut buffer
= number
.to_le_bytes();
118 let now
= time
::Instant
::now();
119 match socket
.send(&buffer
) {
122 match socket
.recv(&mut buffer
) {
123 Ok(size_received
) => {
124 if size_received
== 8 {
125 let number_received
= u64::from_le_bytes(buffer
);
126 if number_received
!= number
{
127 return Err(PingError
::WrongMessageReceived(format!(
128 "Message number receceived ({}) is not equal to the one sent ({})",
129 number_received
, number
133 return Err(PingError
::WrongMessageReceived(format!(
134 "Size of packet must be 8, received size: {}",
139 Err(error
) => return Err(PingError
::SocketError(error
)),
142 Err(error
) => return Err(PingError
::SocketError(error
)),
145 Ok(time
::Instant
::now() - now
)
148 fn send_email(title
: &str, body
: &str, login
: &str, pass
: &str) -> Result
<()> {
149 let email
= Message
::builder()
151 .from("Staking Watchdog <redmine@d-lan.net>".parse()?
)
152 .to("Greg Burri <greg.burri@gmail.com>".parse()?
)
154 .header(ContentType
::TEXT_PLAIN
)
155 .body(body
.to_string())?
;
157 let creds
= Credentials
::new(login
.to_string(), pass
.to_string());
159 // Open a remote connection to gmail
160 let mailer
= SmtpTransport
::relay("mail.gandi.net")?
165 let response
= mailer
.send(&email
)?
;
167 println!("{:?}", response
);