c7791a0168d9a505f7a4b3e87b1d3e2df3c34b9c
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.
22 const SOCKET_TIMEOUT
: Duration
= Duration
::from_secs(7);
24 fn main() -> Result
<()> {
25 println!("Staking Watchdog Watchdog");
27 let config
= Config
::read(FILE_CONF
)?
;
30 "Configuration: {:?}",
32 smtp_password
: "*****".to_string(),
37 let mut time_last_email_send
= time
::Instant
::now() - EMAIL_RESEND_PERIOD
;
38 let mut time_last_state_printed
= time
::Instant
::now() - STATE_PRINT_PERIOD
;
39 let mut error_state
= false;
41 let mut rng
= rand
::thread_rng();
43 let mut number_of_pings
= 0;
44 let mut total_ping_duration
= Duration
::default();
46 let socket
= UdpSocket
::bind("0.0.0.0:0").unwrap();
47 socket
.connect("192.168.2.102:8739").unwrap();
48 socket
.set_nonblocking(false).unwrap();
49 socket
.set_read_timeout(Some(SOCKET_TIMEOUT
)).unwrap();
50 socket
.set_write_timeout(Some(SOCKET_TIMEOUT
)).unwrap();
53 let time_beginning_loop
= time
::Instant
::now();
55 match ping(&socket
, &mut rng
) {
57 total_ping_duration
+= t
;
62 println!("End of erroneous state");
65 if time
::Instant
::now() - time_last_state_printed
>= STATE_PRINT_PERIOD
{
67 "No error detected. Mean of ping time: {} μs",
68 total_ping_duration
.as_micros() / number_of_pings
70 total_ping_duration
= Duration
::default();
72 time_last_state_printed
= time
::Instant
::now();
77 println!("Error: {:?}", error
);
78 if time
::Instant
::now() - time_last_email_send
>= EMAIL_RESEND_PERIOD
{
80 println!("Sending email...");
82 "Watchdog Watchdog ERROR",
83 &format!("Error: {:?}", error
),
85 &config
.smtp_password
,
87 Err(email_error
) => println!("Error sending email: {:?}", email_error
),
89 println!("Email successfully sent");
90 time_last_email_send
= time
::Instant
::now();
97 let elapsed
= time
::Instant
::now() - time_beginning_loop
;
99 if elapsed
< PING_PERIOD
{
100 let to_wait
= PING_PERIOD
- elapsed
;
101 thread
::sleep(to_wait
);
108 SocketReceiveError(std
::io
::Error
),
109 SocketSendError(std
::io
::Error
),
110 WrongMessageReceived(String
),
113 fn ping(socket
: &UdpSocket
, rng
: &mut ThreadRng
) -> std
::result
::Result
<Duration
, PingError
> {
114 let number
: u64 = rng
.gen();
115 let mut buffer
= number
.to_le_bytes();
117 let now
= time
::Instant
::now();
118 match socket
.send(&buffer
) {
121 match socket
.recv(&mut buffer
) {
122 Ok(size_received
) => {
123 if size_received
== 8 {
124 let number_received
= u64::from_le_bytes(buffer
);
125 if number_received
!= number
{
126 return Err(PingError
::WrongMessageReceived(format!(
127 "Message number receceived ({}) is not equal to the one sent ({})",
128 number_received
, number
132 return Err(PingError
::WrongMessageReceived(format!(
133 "Size of packet must be 8, received size: {}",
138 Err(error
) => return Err(PingError
::SocketReceiveError(error
)),
141 Err(error
) => return Err(PingError
::SocketSendError(error
)),
144 Ok(time
::Instant
::now() - now
)
147 fn send_email(title
: &str, body
: &str, login
: &str, pass
: &str) -> Result
<()> {
148 let email
= Message
::builder()
150 .from("Staking Watchdog Watchdog <redmine@d-lan.net>".parse()?
)
151 .to("Greg Burri <greg.burri@gmail.com>".parse()?
)
153 .header(ContentType
::TEXT_PLAIN
)
154 .body(body
.to_string())?
;
156 let creds
= Credentials
::new(login
.to_string(), pass
.to_string());
158 // Open a remote connection to gmail
159 let mailer
= SmtpTransport
::relay("mail.gandi.net")?
164 let response
= mailer
.send(&email
)?
;
166 println!("{:?}", response
);