Fixed problems on stats file when dropping perms

pull/46/head
Dennis Schwerdel 2019-12-06 09:55:24 +01:00
parent 04e2892c8e
commit cd09311059
3 changed files with 48 additions and 20 deletions

View File

@ -2,6 +2,13 @@
This project follows [semantic versioning](http://semver.org).
### Unreleased
- [changed] Also drop privileges in foreground mode
- [changed] Set builders to Ubuntu 16.04 and CentOS 7
- [fixed] Added parameter keepalive to manpage
- [fixed] Fixed problems on stats file when dropping permissions
### v1.1.0 (2019-12-04)
- [added] Exchange peer timeout and adapt keepalive accordingly

View File

@ -6,12 +6,11 @@ use std::{
cmp::min,
collections::HashMap,
fmt,
fs::{self, File, Permissions},
fs::File,
hash::BuildHasherDefault,
io::{self, Write},
marker::PhantomData,
net::{SocketAddr, ToSocketAddrs},
os::unix::fs::PermissionsExt
net::{SocketAddr, ToSocketAddrs}
};
use fnv::FnvHasher;
@ -230,6 +229,7 @@ pub struct GenericCloud<D: Device, P: Protocol, T: Table, S: Socket, TS: TimeSou
peer_timeout_publish: u16,
update_freq: u16,
buffer_out: [u8; 64 * 1024],
stats_file: Option<File>,
next_housekeep: Time,
next_stats_out: Time,
next_beacon: Time,
@ -244,7 +244,7 @@ impl<D: Device, P: Protocol, T: Table, S: Socket, TS: TimeSource> GenericCloud<D
#[allow(clippy::too_many_arguments)]
pub fn new(
config: &Config, device: D, table: T, learning: bool, broadcast: bool, addresses: Vec<Range>, crypto: Crypto,
port_forwarding: Option<PortForwarding>
port_forwarding: Option<PortForwarding>, stats_file: Option<File>
) -> Self
{
let socket4 = match S::listen_v4("0.0.0.0", config.port) {
@ -278,6 +278,7 @@ impl<D: Device, P: Protocol, T: Table, S: Socket, TS: TimeSource> GenericCloud<D
device,
next_peerlist: now,
update_freq: config.get_keepalive() as u16,
stats_file,
buffer_out: [0; 64 * 1024],
next_housekeep: now,
next_stats_out: now + STATS_INTERVAL,
@ -586,18 +587,16 @@ impl<D: Device, P: Protocol, T: Table, S: Socket, TS: TimeSource> GenericCloud<D
/// Calculates, resets and writes out the statistics to a file
fn write_out_stats(&mut self) -> Result<(), io::Error> {
if self.config.stats_file.is_none() {
return Ok(())
if let Some(ref mut f) = self.stats_file {
debug!("Writing out stats");
f.set_len(0)?;
self.peers.write_out(f)?;
writeln!(f)?;
self.table.write_out(f)?;
writeln!(f)?;
self.traffic.write_out(f)?;
writeln!(f)?;
}
debug!("Writing out stats");
let mut f = File::create(self.config.stats_file.as_ref().unwrap())?;
self.peers.write_out(&mut f)?;
writeln!(&mut f)?;
self.table.write_out(&mut f)?;
writeln!(&mut f)?;
self.traffic.write_out(&mut f)?;
writeln!(&mut f)?;
fs::set_permissions(self.config.stats_file.as_ref().unwrap(), Permissions::from_mode(0o644))?;
Ok(())
}

View File

@ -33,9 +33,10 @@ pub mod udpmessage;
use docopt::Docopt;
use std::{
fs::File,
fs::{self, File, Permissions},
io::{self, Write},
net::UdpSocket,
os::unix::fs::PermissionsExt,
path::Path,
process::Command,
str::FromStr,
@ -166,7 +167,7 @@ impl<P: Protocol> AnyCloud<P> {
#[allow(unknown_lints, clippy::too_many_arguments)]
fn new(
config: &Config, device: TunTapDevice, table: AnyTable, learning: bool, broadcast: bool, addresses: Vec<Range>,
crypto: Crypto, port_forwarding: Option<PortForwarding>
crypto: Crypto, port_forwarding: Option<PortForwarding>, stats_file: Option<File>
) -> Self
{
match table {
@ -178,7 +179,15 @@ impl<P: Protocol> AnyCloud<P> {
UdpSocket,
SystemTimeSource
>::new(
config, device, t, learning, broadcast, addresses, crypto, port_forwarding
config,
device,
t,
learning,
broadcast,
addresses,
crypto,
port_forwarding,
stats_file
))
}
AnyTable::Routing(t) => {
@ -190,7 +199,8 @@ impl<P: Protocol> AnyCloud<P> {
broadcast,
addresses,
crypto,
port_forwarding
port_forwarding,
stats_file
))
}
}
@ -256,7 +266,19 @@ fn run<P: Protocol>(config: Config) {
None => Crypto::None
};
let port_forwarding = if config.port_forwarding { PortForwarding::new(config.port) } else { None };
let mut cloud = AnyCloud::<P>::new(&config, device, table, learning, broadcasting, ranges, crypto, port_forwarding);
let stats_file = match config.stats_file {
None => None,
Some(ref name) => {
let file = try_fail!(File::create(name), "Failed to create stats file: {}");
try_fail!(
fs::set_permissions(name, Permissions::from_mode(0o644)),
"Failed to set permissions on stats file: {}"
);
Some(file)
}
};
let mut cloud =
AnyCloud::<P>::new(&config, device, table, learning, broadcasting, ranges, crypto, port_forwarding, stats_file);
if let Some(script) = config.ifup {
run_script(&script, cloud.ifname());
}