mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2025-02-25 15:10:48 +01:00
Merge remote-tracking branch 'isis/bug23881_r1'
This commit is contained in:
commit
d8893bc93c
17 changed files with 423 additions and 24 deletions
|
@ -52,6 +52,13 @@
|
||||||
|
|
||||||
#define raw_assert(x) assert(x) // assert OK
|
#define raw_assert(x) assert(x) // assert OK
|
||||||
|
|
||||||
|
/** Defining compile-time constants for Tor log levels (used by the Rust
|
||||||
|
* log wrapper at src/rust/tor_log) */
|
||||||
|
const int LOG_WARN_ = LOG_WARN;
|
||||||
|
const int LOG_NOTICE_ = LOG_NOTICE;
|
||||||
|
const log_domain_mask_t LD_GENERAL_ = LD_GENERAL;
|
||||||
|
const log_domain_mask_t LD_NET_ = LD_NET;
|
||||||
|
|
||||||
/** Information for a single logfile; only used in log.c */
|
/** Information for a single logfile; only used in log.c */
|
||||||
typedef struct logfile_t {
|
typedef struct logfile_t {
|
||||||
struct logfile_t *next; /**< Next logfile_t in the linked list. */
|
struct logfile_t *next; /**< Next logfile_t in the linked list. */
|
||||||
|
@ -225,6 +232,30 @@ log_set_application_name(const char *name)
|
||||||
appname = name ? tor_strdup(name) : NULL;
|
appname = name ? tor_strdup(name) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Return true if some of the running logs might be interested in a log
|
||||||
|
* message of the given severity in the given domains. If this function
|
||||||
|
* returns true, the log message might be ignored anyway, but if it returns
|
||||||
|
* false, it is definitely_ safe not to log the message. */
|
||||||
|
int
|
||||||
|
log_message_is_interesting(int severity, log_domain_mask_t domain)
|
||||||
|
{
|
||||||
|
(void) domain;
|
||||||
|
return (severity <= log_global_min_severity_);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* As tor_log, but takes an optional function name, and does not treat its
|
||||||
|
* <b>string</b> as a printf format.
|
||||||
|
*
|
||||||
|
* For use by Rust integration.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
tor_log_string(int severity, log_domain_mask_t domain,
|
||||||
|
const char *function, const char *string)
|
||||||
|
{
|
||||||
|
log_fn_(severity, domain, function, "%s", string);
|
||||||
|
}
|
||||||
|
|
||||||
/** Log time granularity in milliseconds. */
|
/** Log time granularity in milliseconds. */
|
||||||
static int log_time_granularity = 1;
|
static int log_time_granularity = 1;
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,16 @@
|
||||||
* "maximum severity" read "most severe" and "numerically *lowest* severity".
|
* "maximum severity" read "most severe" and "numerically *lowest* severity".
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/** This defines log levels that are linked in the Rust log module, rather
|
||||||
|
* than re-defining these in both Rust and C.
|
||||||
|
*
|
||||||
|
* C_RUST_COUPLED src/rust/tor_log LogSeverity, LogDomain
|
||||||
|
*/
|
||||||
|
extern const int LOG_WARN_;
|
||||||
|
extern const int LOG_NOTICE_;
|
||||||
|
extern const log_domain_mask_t LD_NET_;
|
||||||
|
extern const log_domain_mask_t LD_GENERAL_;
|
||||||
|
|
||||||
/** Debug-level severity: for hyper-verbose messages of no interest to
|
/** Debug-level severity: for hyper-verbose messages of no interest to
|
||||||
* anybody but developers. */
|
* anybody but developers. */
|
||||||
#define LOG_DEBUG 7
|
#define LOG_DEBUG 7
|
||||||
|
@ -191,6 +201,10 @@ void log_fn_ratelim_(struct ratelim_t *ratelim, int severity,
|
||||||
const char *format, ...)
|
const char *format, ...)
|
||||||
CHECK_PRINTF(5,6);
|
CHECK_PRINTF(5,6);
|
||||||
|
|
||||||
|
int log_message_is_interesting(int severity, log_domain_mask_t domain);
|
||||||
|
void tor_log_string(int severity, log_domain_mask_t domain,
|
||||||
|
const char *function, const char *string);
|
||||||
|
|
||||||
#if defined(__GNUC__) && __GNUC__ <= 3
|
#if defined(__GNUC__) && __GNUC__ <= 3
|
||||||
|
|
||||||
/* These are the GCC varidaic macros, so that older versions of GCC don't
|
/* These are the GCC varidaic macros, so that older versions of GCC don't
|
||||||
|
|
|
@ -133,7 +133,7 @@ void evdns_shutdown(int);
|
||||||
#ifdef HAVE_RUST
|
#ifdef HAVE_RUST
|
||||||
// helper function defined in Rust to output a log message indicating if tor is
|
// helper function defined in Rust to output a log message indicating if tor is
|
||||||
// running with Rust enabled. See src/rust/tor_util
|
// running with Rust enabled. See src/rust/tor_util
|
||||||
char *rust_welcome_string(void);
|
void rust_log_welcome_string(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/********* PROTOTYPES **********/
|
/********* PROTOTYPES **********/
|
||||||
|
@ -3344,11 +3344,7 @@ tor_init(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_RUST
|
#ifdef HAVE_RUST
|
||||||
char *rust_str = rust_welcome_string();
|
rust_log_welcome_string();
|
||||||
if (rust_str != NULL && strlen(rust_str) > 0) {
|
|
||||||
log_notice(LD_GENERAL, "%s", rust_str);
|
|
||||||
}
|
|
||||||
tor_free(rust_str);
|
|
||||||
#endif /* defined(HAVE_RUST) */
|
#endif /* defined(HAVE_RUST) */
|
||||||
|
|
||||||
if (network_init()<0) {
|
if (network_init()<0) {
|
||||||
|
|
10
src/rust/Cargo.lock
generated
10
src/rust/Cargo.lock
generated
|
@ -4,6 +4,7 @@ version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"tor_allocate 0.0.1",
|
"tor_allocate 0.0.1",
|
||||||
|
"tor_log 0.1.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -26,6 +27,7 @@ dependencies = [
|
||||||
"libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"smartlist 0.0.1",
|
"smartlist 0.0.1",
|
||||||
"tor_allocate 0.0.1",
|
"tor_allocate 0.0.1",
|
||||||
|
"tor_log 0.1.0",
|
||||||
"tor_util 0.0.1",
|
"tor_util 0.0.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -43,6 +45,14 @@ dependencies = [
|
||||||
"libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tor_log"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"libc 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"tor_allocate 0.0.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tor_rust"
|
name = "tor_rust"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
[workspace]
|
[workspace]
|
||||||
members = ["tor_util", "protover", "smartlist", "external", "tor_allocate", "tor_rust"]
|
members = ["tor_util", "protover", "smartlist", "external", "tor_allocate",
|
||||||
|
"tor_rust", "tor_log"]
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
debug = true
|
debug = true
|
||||||
|
|
|
@ -3,6 +3,9 @@ authors = ["The Tor Project"]
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
name = "protover"
|
name = "protover"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
testing = ["tor_log/testing"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libc = "0.2.22"
|
libc = "0.2.22"
|
||||||
|
|
||||||
|
@ -18,6 +21,9 @@ path = "../tor_util"
|
||||||
[dependencies.tor_allocate]
|
[dependencies.tor_allocate]
|
||||||
path = "../tor_allocate"
|
path = "../tor_allocate"
|
||||||
|
|
||||||
|
[dependencies.tor_log]
|
||||||
|
path = "../tor_log"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "protover"
|
name = "protover"
|
||||||
path = "lib.rs"
|
path = "lib.rs"
|
||||||
|
|
|
@ -127,9 +127,11 @@ pub extern "C" fn protocol_list_supports_protocol_or_later(
|
||||||
Err(_) => return 0,
|
Err(_) => return 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
let is_supported =
|
let is_supported = protover_string_supports_protocol_or_later(
|
||||||
protover_string_supports_protocol_or_later(
|
protocol_list,
|
||||||
protocol_list, protocol, version);
|
protocol,
|
||||||
|
version,
|
||||||
|
);
|
||||||
|
|
||||||
return if is_supported { 1 } else { 0 };
|
return if is_supported { 1 } else { 0 };
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,9 @@ extern crate tor_allocate;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate tor_util;
|
extern crate tor_util;
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate tor_log;
|
||||||
|
|
||||||
mod protover;
|
mod protover;
|
||||||
pub mod ffi;
|
pub mod ffi;
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
// Copyright (c) 2016-2017, The Tor Project, Inc. */
|
// Copyright (c) 2016-2017, The Tor Project, Inc. */
|
||||||
// See LICENSE for licensing information */
|
// See LICENSE for licensing information */
|
||||||
|
|
||||||
use external::c_tor_version_as_new_as;
|
|
||||||
|
|
||||||
use std::str;
|
use std::str;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
|
@ -12,6 +10,9 @@ use std::ops::Range;
|
||||||
use std::string::String;
|
use std::string::String;
|
||||||
use std::u32;
|
use std::u32;
|
||||||
|
|
||||||
|
use tor_log::{LogSeverity, LogDomain};
|
||||||
|
use external::c_tor_version_as_new_as;
|
||||||
|
|
||||||
/// The first version of Tor that included "proto" entries in its descriptors.
|
/// The first version of Tor that included "proto" entries in its descriptors.
|
||||||
/// Authorities should use this to decide whether to guess proto lines.
|
/// Authorities should use this to decide whether to guess proto lines.
|
||||||
///
|
///
|
||||||
|
@ -225,7 +226,6 @@ impl Versions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Parse the subprotocol type and its version numbers.
|
/// Parse the subprotocol type and its version numbers.
|
||||||
///
|
///
|
||||||
/// # Inputs
|
/// # Inputs
|
||||||
|
@ -279,6 +279,20 @@ fn get_proto_and_vers<'a>(
|
||||||
fn contains_only_supported_protocols(proto_entry: &str) -> bool {
|
fn contains_only_supported_protocols(proto_entry: &str) -> bool {
|
||||||
let (name, mut vers) = match get_proto_and_vers(proto_entry) {
|
let (name, mut vers) = match get_proto_and_vers(proto_entry) {
|
||||||
Ok(n) => n,
|
Ok(n) => n,
|
||||||
|
Err("Too many versions to expand") => {
|
||||||
|
tor_log_msg!(
|
||||||
|
LogSeverity::Warn,
|
||||||
|
LogDomain::Net,
|
||||||
|
"get_versions",
|
||||||
|
"When expanding a protocol list from an authority, I \
|
||||||
|
got too many protocols. This is possibly an attack or a bug, \
|
||||||
|
unless the Tor network truly has expanded to support over {} \
|
||||||
|
different subprotocol versions. The offending string was: {}",
|
||||||
|
MAX_PROTOCOLS_TO_EXPAND,
|
||||||
|
proto_entry
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
Err(_) => return false,
|
Err(_) => return false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,17 @@
|
||||||
// Copyright (c) 2016-2017, The Tor Project, Inc. */
|
// Copyright (c) 2016-2017, The Tor Project, Inc. */
|
||||||
// See LICENSE for licensing information */
|
// See LICENSE for licensing information */
|
||||||
|
// No-op defined purely for testing at the module level
|
||||||
|
use libc::c_char;
|
||||||
|
|
||||||
use libc::{c_char, c_void};
|
#[cfg(not(feature = "testing"))]
|
||||||
use std::{ptr, slice, mem};
|
use std::{ptr, slice, mem};
|
||||||
|
use libc::c_void;
|
||||||
|
|
||||||
#[cfg(not(test))]
|
// Define a no-op implementation for testing Rust modules without linking to C
|
||||||
extern "C" {
|
#[cfg(feature = "testing")]
|
||||||
fn tor_malloc_(size: usize) -> *mut c_void;
|
pub fn allocate_and_copy_string(s: &String) -> *mut c_char {
|
||||||
|
use std::ffi::CString;
|
||||||
|
CString::new(s.as_str()).unwrap().into_raw()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Defined only for tests, used for testing purposes, so that we don't need
|
// Defined only for tests, used for testing purposes, so that we don't need
|
||||||
|
@ -17,6 +22,11 @@ unsafe extern "C" fn tor_malloc_(size: usize) -> *mut c_void {
|
||||||
malloc(size)
|
malloc(size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(all(not(test), not(feature = "testing")))]
|
||||||
|
extern "C" {
|
||||||
|
fn tor_malloc_(size: usize) -> *mut c_void;
|
||||||
|
}
|
||||||
|
|
||||||
/// Allocate memory using tor_malloc_ and copy an existing string into the
|
/// Allocate memory using tor_malloc_ and copy an existing string into the
|
||||||
/// allocated buffer, returning a pointer that can later be called in C.
|
/// allocated buffer, returning a pointer that can later be called in C.
|
||||||
///
|
///
|
||||||
|
@ -28,6 +38,7 @@ unsafe extern "C" fn tor_malloc_(size: usize) -> *mut c_void {
|
||||||
///
|
///
|
||||||
/// A `*mut c_char` that should be freed by tor_free in C
|
/// A `*mut c_char` that should be freed by tor_free in C
|
||||||
///
|
///
|
||||||
|
#[cfg(not(feature = "testing"))]
|
||||||
pub fn allocate_and_copy_string(src: &String) -> *mut c_char {
|
pub fn allocate_and_copy_string(src: &String) -> *mut c_char {
|
||||||
let bytes: &[u8] = src.as_bytes();
|
let bytes: &[u8] = src.as_bytes();
|
||||||
|
|
||||||
|
|
18
src/rust/tor_log/Cargo.toml
Normal file
18
src/rust/tor_log/Cargo.toml
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
[package]
|
||||||
|
name = "tor_log"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["The Tor Project"]
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
name = "tor_log"
|
||||||
|
path = "lib.rs"
|
||||||
|
crate_type = ["rlib", "staticlib"]
|
||||||
|
|
||||||
|
[features]
|
||||||
|
testing = []
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
libc = "0.2.22"
|
||||||
|
|
||||||
|
[dependencies.tor_allocate]
|
||||||
|
path = "../tor_allocate"
|
16
src/rust/tor_log/lib.rs
Normal file
16
src/rust/tor_log/lib.rs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
//! Copyright (c) 2016-2017, The Tor Project, Inc. */
|
||||||
|
//! See LICENSE for licensing information */
|
||||||
|
|
||||||
|
//! Logging wrapper for Rust to utilize Tor's logger, found at
|
||||||
|
//! src/common/log.c and src/common/torlog.h
|
||||||
|
//!
|
||||||
|
//! Exposes different interfaces depending on whether we are running in test
|
||||||
|
//! or non-test mode. When testing, we use a no-op implementation,
|
||||||
|
//! otherwise we link directly to C.
|
||||||
|
|
||||||
|
extern crate libc;
|
||||||
|
extern crate tor_allocate;
|
||||||
|
|
||||||
|
mod tor_log;
|
||||||
|
|
||||||
|
pub use tor_log::*;
|
270
src/rust/tor_log/tor_log.rs
Normal file
270
src/rust/tor_log/tor_log.rs
Normal file
|
@ -0,0 +1,270 @@
|
||||||
|
// Copyright (c) 2016-2017, The Tor Project, Inc. */
|
||||||
|
// See LICENSE for licensing information */
|
||||||
|
|
||||||
|
// Note that these functions are untested due to the fact that there are no
|
||||||
|
// return variables to test and they are calling into a C API.
|
||||||
|
|
||||||
|
/// The related domain which the logging message is relevant. For example,
|
||||||
|
/// log messages relevant to networking would use LogDomain::LdNet, whereas
|
||||||
|
/// general messages can use LdGeneral.
|
||||||
|
#[derive(Eq, PartialEq)]
|
||||||
|
pub enum LogDomain {
|
||||||
|
Net,
|
||||||
|
General,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The severity level at which to log messages.
|
||||||
|
#[derive(Eq, PartialEq)]
|
||||||
|
pub enum LogSeverity {
|
||||||
|
Notice,
|
||||||
|
Warn,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Main entry point for Rust modules to log messages.
|
||||||
|
///
|
||||||
|
/// # Inputs
|
||||||
|
///
|
||||||
|
/// * A `severity` of type LogSeverity, which defines the level of severity the
|
||||||
|
/// message will be logged.
|
||||||
|
/// * A `domain` of type LogDomain, which defines the domain the log message
|
||||||
|
/// will be associated with.
|
||||||
|
/// * A `function` of type &str, which defines the name of the function where
|
||||||
|
/// the message is being logged. There is a current RFC for a macro that
|
||||||
|
/// defines function names. When it is, we should use it. See
|
||||||
|
/// https://github.com/rust-lang/rfcs/pull/1719
|
||||||
|
/// * A `message` of type &str, which is the log message itself.
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! tor_log_msg {
|
||||||
|
($severity: path,
|
||||||
|
$domain: path,
|
||||||
|
$function: expr,
|
||||||
|
$($message:tt)*) =>
|
||||||
|
{
|
||||||
|
{
|
||||||
|
let msg = format!($($message)*);
|
||||||
|
$crate::tor_log_msg_impl($severity, $domain, $function, msg)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn tor_log_msg_impl(
|
||||||
|
severity: LogSeverity,
|
||||||
|
domain: LogDomain,
|
||||||
|
function: &str,
|
||||||
|
message: String,
|
||||||
|
) {
|
||||||
|
use std::ffi::CString;
|
||||||
|
|
||||||
|
/// Default function name to log in case of errors when converting
|
||||||
|
/// a function name to a CString
|
||||||
|
const ERR_LOG_FUNCTION: &str = "tor_log_msg";
|
||||||
|
|
||||||
|
/// Default message to log in case of errors when converting a log
|
||||||
|
/// message to a CString
|
||||||
|
const ERR_LOG_MSG: &str = "Unable to log message from Rust \
|
||||||
|
module due to error when converting to CString";
|
||||||
|
|
||||||
|
let func = match CString::new(function) {
|
||||||
|
Ok(n) => n,
|
||||||
|
Err(_) => CString::new(ERR_LOG_FUNCTION).unwrap(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let msg = match CString::new(message) {
|
||||||
|
Ok(n) => n,
|
||||||
|
Err(_) => CString::new(ERR_LOG_MSG).unwrap(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Bind to a local variable to preserve ownership. This is essential so
|
||||||
|
// that ownership is guaranteed until these local variables go out of scope
|
||||||
|
let func_ptr = func.as_ptr();
|
||||||
|
let msg_ptr = msg.as_ptr();
|
||||||
|
|
||||||
|
let c_severity = unsafe { log::translate_severity(severity) };
|
||||||
|
let c_domain = unsafe { log::translate_domain(domain) };
|
||||||
|
|
||||||
|
unsafe { log::tor_log_string(c_severity, c_domain, func_ptr, msg_ptr) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This implementation is used when compiling for actual use, as opposed to
|
||||||
|
/// testing.
|
||||||
|
#[cfg(all(not(test), not(feature = "testing")))]
|
||||||
|
pub mod log {
|
||||||
|
use libc::{c_char, c_int};
|
||||||
|
use super::LogDomain;
|
||||||
|
use super::LogSeverity;
|
||||||
|
|
||||||
|
/// Severity log types. These mirror definitions in /src/common/torlog.h
|
||||||
|
/// C_RUST_COUPLED: src/common/log.c, log domain types
|
||||||
|
extern "C" {
|
||||||
|
static LOG_WARN_: c_int;
|
||||||
|
static LOG_NOTICE_: c_int;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Domain log types. These mirror definitions in /src/common/torlog.h
|
||||||
|
/// C_RUST_COUPLED: src/common/log.c, log severity types
|
||||||
|
extern "C" {
|
||||||
|
static LD_NET_: u32;
|
||||||
|
static LD_GENERAL_: u32;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Translate Rust defintions of log domain levels to C. This exposes a 1:1
|
||||||
|
/// mapping between types.
|
||||||
|
#[inline]
|
||||||
|
pub unsafe fn translate_domain(domain: LogDomain) -> u32 {
|
||||||
|
match domain {
|
||||||
|
LogDomain::Net => LD_NET_,
|
||||||
|
LogDomain::General => LD_GENERAL_,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Translate Rust defintions of log severity levels to C. This exposes a
|
||||||
|
/// 1:1 mapping between types.
|
||||||
|
#[inline]
|
||||||
|
pub unsafe fn translate_severity(severity: LogSeverity) -> c_int {
|
||||||
|
match severity {
|
||||||
|
LogSeverity::Warn => LOG_WARN_,
|
||||||
|
LogSeverity::Notice => LOG_NOTICE_,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The main entry point into Tor's logger. When in non-test mode, this
|
||||||
|
/// will link directly with `tor_log_string` in /src/or/log.c
|
||||||
|
extern "C" {
|
||||||
|
pub fn tor_log_string(
|
||||||
|
severity: c_int,
|
||||||
|
domain: u32,
|
||||||
|
function: *const c_char,
|
||||||
|
string: *const c_char,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This module exposes no-op functionality for testing other Rust modules
|
||||||
|
/// without linking to C.
|
||||||
|
#[cfg(any(test, feature = "testing"))]
|
||||||
|
pub mod log {
|
||||||
|
use libc::{c_char, c_int};
|
||||||
|
use super::LogDomain;
|
||||||
|
use super::LogSeverity;
|
||||||
|
|
||||||
|
pub static mut LAST_LOGGED_FUNCTION: *mut String = 0 as *mut String;
|
||||||
|
pub static mut LAST_LOGGED_MESSAGE: *mut String = 0 as *mut String;
|
||||||
|
|
||||||
|
pub unsafe fn tor_log_string(
|
||||||
|
_severity: c_int,
|
||||||
|
_domain: u32,
|
||||||
|
function: *const c_char,
|
||||||
|
message: *const c_char,
|
||||||
|
) {
|
||||||
|
use std::ffi::CStr;
|
||||||
|
|
||||||
|
let f = CStr::from_ptr(function);
|
||||||
|
let fct = match f.to_str() {
|
||||||
|
Ok(n) => n,
|
||||||
|
Err(_) => "",
|
||||||
|
};
|
||||||
|
LAST_LOGGED_FUNCTION = Box::into_raw(Box::new(String::from(fct)));
|
||||||
|
|
||||||
|
let m = CStr::from_ptr(message);
|
||||||
|
let msg = match m.to_str() {
|
||||||
|
Ok(n) => n,
|
||||||
|
Err(_) => "",
|
||||||
|
};
|
||||||
|
LAST_LOGGED_MESSAGE = Box::into_raw(Box::new(String::from(msg)));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn translate_domain(_domain: LogDomain) -> u32 {
|
||||||
|
1
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn translate_severity(_severity: LogSeverity) -> c_int {
|
||||||
|
1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use tor_log::*;
|
||||||
|
use tor_log::log::{LAST_LOGGED_FUNCTION, LAST_LOGGED_MESSAGE};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_get_log_message() {
|
||||||
|
{
|
||||||
|
fn test_macro() {
|
||||||
|
tor_log_msg!(
|
||||||
|
LogSeverity::Warn,
|
||||||
|
LogDomain::Net,
|
||||||
|
"test_macro",
|
||||||
|
"test log message {}",
|
||||||
|
"a",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
test_macro();
|
||||||
|
|
||||||
|
let function = unsafe { Box::from_raw(LAST_LOGGED_FUNCTION) };
|
||||||
|
assert_eq!("test_macro", *function);
|
||||||
|
|
||||||
|
let message = unsafe { Box::from_raw(LAST_LOGGED_MESSAGE) };
|
||||||
|
assert_eq!("test log message a", *message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// test multiple inputs into the log message
|
||||||
|
{
|
||||||
|
fn test_macro() {
|
||||||
|
tor_log_msg!(
|
||||||
|
LogSeverity::Warn,
|
||||||
|
LogDomain::Net,
|
||||||
|
"next_test_macro",
|
||||||
|
"test log message {} {} {} {} {}",
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
4,
|
||||||
|
5
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
test_macro();
|
||||||
|
|
||||||
|
let function = unsafe { Box::from_raw(LAST_LOGGED_FUNCTION) };
|
||||||
|
assert_eq!("next_test_macro", *function);
|
||||||
|
|
||||||
|
let message = unsafe { Box::from_raw(LAST_LOGGED_MESSAGE) };
|
||||||
|
assert_eq!("test log message 1 2 3 4 5", *message);
|
||||||
|
}
|
||||||
|
|
||||||
|
// test how a long log message will be formatted
|
||||||
|
{
|
||||||
|
fn test_macro() {
|
||||||
|
tor_log_msg!(
|
||||||
|
LogSeverity::Warn,
|
||||||
|
LogDomain::Net,
|
||||||
|
"test_macro",
|
||||||
|
"{}",
|
||||||
|
"All the world's a stage, and all the men and women \
|
||||||
|
merely players: they have their exits and their \
|
||||||
|
entrances; and one man in his time plays many parts, his \
|
||||||
|
acts being seven ages."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
test_macro();
|
||||||
|
|
||||||
|
let expected_string = "All the world's a \
|
||||||
|
stage, and all the men \
|
||||||
|
and women merely players: \
|
||||||
|
they have their exits and \
|
||||||
|
their entrances; and one man \
|
||||||
|
in his time plays many parts, \
|
||||||
|
his acts being seven ages.";
|
||||||
|
|
||||||
|
let function = unsafe { Box::from_raw(LAST_LOGGED_FUNCTION) };
|
||||||
|
assert_eq!("test_macro", *function);
|
||||||
|
|
||||||
|
let message = unsafe { Box::from_raw(LAST_LOGGED_MESSAGE) };
|
||||||
|
assert_eq!(expected_string, *message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,6 +11,9 @@ crate_type = ["rlib", "staticlib"]
|
||||||
[dependencies.tor_allocate]
|
[dependencies.tor_allocate]
|
||||||
path = "../tor_allocate"
|
path = "../tor_allocate"
|
||||||
|
|
||||||
|
[dependencies.tor_log]
|
||||||
|
path = "../tor_log"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
libc = "0.2.22"
|
libc = "0.2.22"
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,7 @@
|
||||||
//! called from C.
|
//! called from C.
|
||||||
//!
|
//!
|
||||||
|
|
||||||
use libc::c_char;
|
use tor_log::{LogSeverity, LogDomain};
|
||||||
use tor_allocate::allocate_and_copy_string;
|
|
||||||
|
|
||||||
/// Returns a short string to announce Rust support during startup.
|
/// Returns a short string to announce Rust support during startup.
|
||||||
///
|
///
|
||||||
|
@ -17,10 +16,12 @@ use tor_allocate::allocate_and_copy_string;
|
||||||
/// tor_free(rust_str);
|
/// tor_free(rust_str);
|
||||||
/// ```
|
/// ```
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn rust_welcome_string() -> *mut c_char {
|
pub extern "C" fn rust_log_welcome_string() {
|
||||||
let rust_welcome = String::from(
|
tor_log_msg!(
|
||||||
|
LogSeverity::Notice,
|
||||||
|
LogDomain::General,
|
||||||
|
"rust_log_welcome_string",
|
||||||
"Tor is running with Rust integration. Please report \
|
"Tor is running with Rust integration. Please report \
|
||||||
any bugs you encounter.",
|
any bugs you encounter."
|
||||||
);
|
);
|
||||||
allocate_and_copy_string(&rust_welcome)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,5 +7,8 @@
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
extern crate tor_allocate;
|
extern crate tor_allocate;
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate tor_log;
|
||||||
|
|
||||||
pub mod ffi;
|
pub mod ffi;
|
||||||
pub mod strings;
|
pub mod strings;
|
||||||
|
|
|
@ -11,7 +11,7 @@ for crate in $crates; do
|
||||||
cd "${abs_top_builddir:-../../..}/src/rust"
|
cd "${abs_top_builddir:-../../..}/src/rust"
|
||||||
CARGO_TARGET_DIR="${abs_top_builddir:-../../..}/src/rust/target" \
|
CARGO_TARGET_DIR="${abs_top_builddir:-../../..}/src/rust/target" \
|
||||||
CARGO_HOME="${abs_top_builddir:-../../..}/src/rust" \
|
CARGO_HOME="${abs_top_builddir:-../../..}/src/rust" \
|
||||||
"${CARGO:-cargo}" test ${CARGO_ONLINE-"--frozen"} \
|
"${CARGO:-cargo}" test --all-features ${CARGO_ONLINE-"--frozen"} \
|
||||||
--manifest-path "${abs_top_srcdir:-.}/src/rust/${crate}/Cargo.toml" \
|
--manifest-path "${abs_top_srcdir:-.}/src/rust/${crate}/Cargo.toml" \
|
||||||
|| exitcode=1
|
|| exitcode=1
|
||||||
cd -
|
cd -
|
||||||
|
|
Loading…
Add table
Reference in a new issue