From aeefa364b7fd386584d90040592ae9b4b3dc42b4 Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Wed, 1 Jul 2015 21:49:11 -0700 Subject: Decouple C SSL Option bit flags from Rust version The OpenSSL "SSL_OP_*" flags are in constant flux between different OpenSSL versions. To avoid having to change the Rust definitions, we implement our own numbering system in Rust, and use an automatically-generated C shim to convert the bitflags at runtime. --- openssl-sys/build.rs | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) (limited to 'openssl-sys/build.rs') diff --git a/openssl-sys/build.rs b/openssl-sys/build.rs index c1f12034..841c7eec 100644 --- a/openssl-sys/build.rs +++ b/openssl-sys/build.rs @@ -2,7 +2,10 @@ extern crate pkg_config; extern crate gcc; use std::env; +use std::fmt::Write as FmtWrite; use std::path::PathBuf; +use std::fs::File; +use std::io::Write; fn main() { let target = env::var("TARGET").unwrap(); @@ -65,7 +68,67 @@ fn main() { build_openssl_shim(&include_dirs); } +macro_rules! import_options { + ( $( $name:ident $val:expr )* ) => { + &[ $( (stringify!($name),$val), )* ] + }; +} + +fn generate_options_shim() -> PathBuf { + let options: &[(&'static str,u64)]=include!("src/ssl_options.rs"); + let mut shim = String::new(); + writeln!(shim,"#include ").unwrap(); + writeln!(shim,"#include ").unwrap(); + + for &(name,value) in options { + writeln!(shim,"#define RUST_{} UINT64_C({})",name,value).unwrap(); + writeln!(shim,"#ifndef {}",name).unwrap(); + writeln!(shim,"# define {} 0",name).unwrap(); + writeln!(shim,"#endif").unwrap(); + } + + writeln!(shim,"#define COPY_MASK ( \\").unwrap(); + + let mut it=options.iter().peekable(); + while let Some(&(name,_))=it.next() { + let eol=match it.peek() { + Some(_) => " | \\", + None => " )" + }; + writeln!(shim," ((RUST_{0}==(uint64_t)(uint32_t){0})?RUST_{0}:UINT64_C(0)){1}",name,eol).unwrap(); + } + + writeln!(shim,"long rust_openssl_ssl_ctx_options_rust_to_c(uint64_t rustval) {{").unwrap(); + writeln!(shim," long cval=rustval©_MASK;").unwrap(); + for &(name,_) in options { + writeln!(shim,"#if RUST_{0}!={0}",name).unwrap(); + writeln!(shim," if (rustval&RUST_{0}) cval|={0};",name).unwrap(); + writeln!(shim,"#endif").unwrap(); + } + writeln!(shim," return cval;").unwrap(); + writeln!(shim,"}}").unwrap(); + + writeln!(shim,"uint64_t rust_openssl_ssl_ctx_options_c_to_rust(long cval) {{").unwrap(); + writeln!(shim," uint64_t rustval=cval©_MASK;").unwrap(); + for &(name,_) in options { + writeln!(shim,"#if RUST_{0}!={0}",name).unwrap(); + writeln!(shim," if (cval&{0}) rustval|=RUST_{0};",name).unwrap(); + writeln!(shim,"#endif").unwrap(); + } + writeln!(shim," return rustval;").unwrap(); + writeln!(shim,"}}").unwrap(); + + let out_dir = env::var("OUT_DIR").unwrap(); + let dest_file = PathBuf::from(&out_dir).join("ssl_ctx_options_shim.c"); + let mut f = File::create(&dest_file).unwrap(); + + f.write_all(shim.as_bytes()).unwrap(); + + dest_file +} + fn build_openssl_shim(include_paths: &[PathBuf]) { + let options_shim_file = generate_options_shim(); let mut config = gcc::Config::new(); for path in include_paths { @@ -73,6 +136,7 @@ fn build_openssl_shim(include_paths: &[PathBuf]) { } config.file("src/openssl_shim.c") + .file(options_shim_file) .compile("libopenssl_shim.a"); } -- cgit v1.2.3 From 6a725acf4ddb949dbc3b1365ebc340b5066bebad Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Mon, 22 Jun 2015 22:28:07 -0700 Subject: Remove #ifs for same-value shimmed SSL options. Depend on compiler optimization instead. --- openssl-sys/build.rs | 4 ---- 1 file changed, 4 deletions(-) (limited to 'openssl-sys/build.rs') diff --git a/openssl-sys/build.rs b/openssl-sys/build.rs index 841c7eec..b4a00566 100644 --- a/openssl-sys/build.rs +++ b/openssl-sys/build.rs @@ -101,9 +101,7 @@ fn generate_options_shim() -> PathBuf { writeln!(shim,"long rust_openssl_ssl_ctx_options_rust_to_c(uint64_t rustval) {{").unwrap(); writeln!(shim," long cval=rustval©_MASK;").unwrap(); for &(name,_) in options { - writeln!(shim,"#if RUST_{0}!={0}",name).unwrap(); writeln!(shim," if (rustval&RUST_{0}) cval|={0};",name).unwrap(); - writeln!(shim,"#endif").unwrap(); } writeln!(shim," return cval;").unwrap(); writeln!(shim,"}}").unwrap(); @@ -111,9 +109,7 @@ fn generate_options_shim() -> PathBuf { writeln!(shim,"uint64_t rust_openssl_ssl_ctx_options_c_to_rust(long cval) {{").unwrap(); writeln!(shim," uint64_t rustval=cval©_MASK;").unwrap(); for &(name,_) in options { - writeln!(shim,"#if RUST_{0}!={0}",name).unwrap(); writeln!(shim," if (cval&{0}) rustval|=RUST_{0};",name).unwrap(); - writeln!(shim,"#endif").unwrap(); } writeln!(shim," return rustval;").unwrap(); writeln!(shim,"}}").unwrap(); -- cgit v1.2.3