-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
765 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
/target | ||
/Cargo.lock | ||
*.a |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
[package] | ||
name = "maybenot-ffi" | ||
description = "An FFI wrapper around Maybenot" | ||
version = "1.0.0" | ||
edition.workspace = true | ||
license.workspace = true | ||
homepage.workspace = true | ||
keywords.workspace = true | ||
categories.workspace = true | ||
repository.workspace = true | ||
|
||
[lib] | ||
crate-type = ["lib", "staticlib", "cdylib"] | ||
|
||
[dependencies] | ||
maybenot = { version = "2.0.0", path = "../maybenot" } | ||
rand = "0.8.5" | ||
rand_chacha = "0.3.1" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
CBINDGEN ?= cbindgen | ||
CARGO ?= cargo | ||
TARGET ?= | ||
PROFILE ?= release | ||
DESTINATION ?= . | ||
CARGO_TARGET_DIR ?= ../../target | ||
|
||
CARGO_OUTPUT_DIR := $(CARGO_TARGET_DIR)/$(TARGET)/$(PROFILE) | ||
CARGOFLAGS += --target-dir $(CARGO_TARGET_DIR) | ||
|
||
ifeq ($(PROFILE), release) | ||
CARGOFLAGS += --release | ||
endif | ||
|
||
ifneq ($(TARGET),) | ||
CARGOFLAGS += --target | ||
CARGOFLAGS += $(TARGET) | ||
endif | ||
|
||
.PHONY: clean | ||
|
||
# copy the library to the final destination, and strip the _ffi part | ||
$(DESTINATION)/libmaybenot.a: $(CARGO_OUTPUT_DIR)/libmaybenot_ffi.a | ||
cp $^ $@ | ||
|
||
# generate maybenot.h | ||
maybenot.h: src/*.rs Cargo.toml cbindgen.toml | ||
${CBINDGEN} -o maybenot.h | ||
|
||
# build the static library | ||
$(CARGO_OUTPUT_DIR)/libmaybenot_ffi.a: maybenot.h src/*.rs Cargo.toml cbindgen.toml | ||
RUSTFLAGS="-C metadata=maybenot-ffi" ${CARGO} build $(CARGOFLAGS) | ||
|
||
clean: | ||
rm -f $(DESTINATION)/libmaybenot.a | ||
${CARGO} clean $(CARGOFLAGS) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# Maybenot FFI | ||
|
||
This crate contains C FFI bindings for Maybenot, which let's you use Maybenot as a static library | ||
for languages other than Rust. Headers are found at `maybenot-ffi/maybenot.h` and are | ||
auto-generated when compiling using `make`. | ||
|
||
## Building | ||
You need to have [rust](https://rustup.rs/) installed. | ||
`cbindgen` is also required: `cargo install --force cbindgen` | ||
Then just run `make` to build a static library at `maybenot-ffi/libmaybenot.a`. | ||
|
||
Arguments to `make`: | ||
- `CARGO` override the `cargo` command | ||
- `TARGET` override target architecture; cross-compile. | ||
- `PROFILE` override the cargo profile, valid options are `release` and `debug`. | ||
- `DESTINATION` change the directory where the output artifacts will be places. | ||
|
||
Example: | ||
``` | ||
make TARGET=x86_64-unknown-linux-gnu PROFILE=debug | ||
``` | ||
|
||
In order to link the resulting library to your program, you'll need to explicitly link some | ||
additional dependencies in addition to `-lmaybenot`. | ||
Run the following command to get an up-to-date list of the required flags for your platform: | ||
``` | ||
RUSTFLAGS="--print native-static-libs" cargo build | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# See https://github.com/mozilla/cbindgen/blob/master/docs.md#cbindgentoml | ||
|
||
language = "C" | ||
|
||
autogen_warning = "/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */" | ||
include_version = true | ||
|
||
[enum] | ||
prefix_with_name = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,229 @@ | ||
/* Generated with cbindgen:0.26.0 */ | ||
|
||
/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */ | ||
|
||
#include <stdarg.h> | ||
#include <stdbool.h> | ||
#include <stdint.h> | ||
#include <stdlib.h> | ||
|
||
enum MaybenotEventType { | ||
MaybenotEventType_NormalRecv = 0, | ||
MaybenotEventType_PaddingRecv = 1, | ||
MaybenotEventType_TunnelRecv = 2, | ||
MaybenotEventType_NormalSent = 3, | ||
MaybenotEventType_PaddingSent = 4, | ||
MaybenotEventType_TunnelSent = 5, | ||
MaybenotEventType_BlockingBegin = 6, | ||
MaybenotEventType_BlockingEnd = 7, | ||
MaybenotEventType_TimerBegin = 8, | ||
MaybenotEventType_TimerEnd = 9, | ||
}; | ||
typedef uint32_t MaybenotEventType; | ||
|
||
/** | ||
* An FFI friendly result error code type. | ||
*/ | ||
enum MaybenotResult { | ||
/** | ||
* Operation completed successfully | ||
*/ | ||
MaybenotResult_Ok = 0, | ||
/** | ||
* The machine string wasn't valid UTF-8 | ||
*/ | ||
MaybenotResult_MachineStringNotUtf8 = 1, | ||
/** | ||
* Failed to parse machine string | ||
*/ | ||
MaybenotResult_InvalidMachineString = 2, | ||
/** | ||
* Failed to start framework | ||
*/ | ||
MaybenotResult_StartFramework = 3, | ||
/** | ||
* A null pointer was encountered | ||
*/ | ||
MaybenotResult_NullPointer = 4, | ||
}; | ||
typedef uint32_t MaybenotResult; | ||
|
||
/** | ||
* The different types of timers used by a [Machine]. | ||
*/ | ||
enum MaybenotTimer { | ||
/** | ||
* The scheduled timer for actions with a timeout. | ||
*/ | ||
MaybenotTimer_Action = 0, | ||
/** | ||
* The machine's internal timer, updated by the machine using [MaybenotAction::UpdateTimer]. | ||
*/ | ||
MaybenotTimer_Internal = 1, | ||
/** | ||
* Apply to all timers. | ||
*/ | ||
MaybenotTimer_All = 2, | ||
}; | ||
typedef uint32_t MaybenotTimer; | ||
|
||
/** | ||
* A running Maybenot instance. | ||
* | ||
* - Create it: [maybenot_start]. | ||
* - Feed it actions: [maybenot_on_events]. | ||
* - Stop it: [maybenot_stop]. | ||
*/ | ||
typedef struct MaybenotFramework MaybenotFramework; | ||
|
||
typedef struct MaybenotEvent { | ||
MaybenotEventType event_type; | ||
/** | ||
* The ID of the machine that triggered the event, if any. | ||
*/ | ||
uintptr_t machine; | ||
} MaybenotEvent; | ||
|
||
typedef struct MaybenotDuration { | ||
/** | ||
* Number of whole seconds | ||
*/ | ||
uint64_t secs; | ||
/** | ||
* A nanosecond fraction of a second. | ||
*/ | ||
uint32_t nanos; | ||
} MaybenotDuration; | ||
|
||
/** | ||
* The action to be taken by the framework user. | ||
*/ | ||
enum MaybenotAction_Tag { | ||
/** | ||
* Cancel the timer for a machine. | ||
*/ | ||
MaybenotAction_Cancel = 0, | ||
/** | ||
* Schedule padding to be injected after the given timeout for a machine. | ||
*/ | ||
MaybenotAction_SendPadding = 1, | ||
/** | ||
* Schedule blocking of outgoing traffic after the given timeout for a machine. | ||
*/ | ||
MaybenotAction_BlockOutgoing = 2, | ||
/** | ||
* Update the timer duration for a machine. | ||
*/ | ||
MaybenotAction_UpdateTimer = 3, | ||
}; | ||
typedef uint32_t MaybenotAction_Tag; | ||
|
||
typedef struct MaybenotAction_Cancel_Body { | ||
/** | ||
* The machine that generated the action. | ||
*/ | ||
uintptr_t machine; | ||
MaybenotTimer timer; | ||
} MaybenotAction_Cancel_Body; | ||
|
||
typedef struct MaybenotAction_SendPadding_Body { | ||
/** | ||
* The machine that generated the action. | ||
*/ | ||
uintptr_t machine; | ||
/** | ||
* The time to wait before injecting a padding packet. | ||
*/ | ||
struct MaybenotDuration timeout; | ||
bool replace; | ||
bool bypass; | ||
} MaybenotAction_SendPadding_Body; | ||
|
||
typedef struct MaybenotAction_BlockOutgoing_Body { | ||
/** | ||
* The machine that generated the action. | ||
*/ | ||
uintptr_t machine; | ||
/** | ||
* The time to wait before blocking. | ||
*/ | ||
struct MaybenotDuration timeout; | ||
bool replace; | ||
bool bypass; | ||
/** | ||
* How long to block. | ||
*/ | ||
struct MaybenotDuration duration; | ||
} MaybenotAction_BlockOutgoing_Body; | ||
|
||
typedef struct MaybenotAction_UpdateTimer_Body { | ||
uintptr_t machine; | ||
struct MaybenotDuration duration; | ||
bool replace; | ||
} MaybenotAction_UpdateTimer_Body; | ||
|
||
typedef struct MaybenotAction { | ||
MaybenotAction_Tag tag; | ||
union { | ||
MaybenotAction_Cancel_Body cancel; | ||
MaybenotAction_SendPadding_Body send_padding; | ||
MaybenotAction_BlockOutgoing_Body block_outgoing; | ||
MaybenotAction_UpdateTimer_Body update_timer; | ||
}; | ||
} MaybenotAction; | ||
|
||
/** | ||
* Get the version of maybenot-ffi as a null terminated UTF-8-string. | ||
* | ||
* Example: `maybenot-ffi/1.0.1` | ||
*/ | ||
const char *maybenot_version(void); | ||
|
||
/** | ||
* Start a new [`MaybenotFramework`] instance. | ||
* | ||
* # Safety | ||
* - `machines_str` must be a null-terminated UTF-8 string, containing LF-separated machines. | ||
* - `out` must be a valid pointer to some valid and aligned pointer-sized memory. | ||
* - The pointer written to `out` is NOT safe to be used concurrently. | ||
*/ | ||
MaybenotResult maybenot_start(const char *machines_str, | ||
double max_padding_frac, | ||
double max_blocking_frac, | ||
struct MaybenotFramework **out); | ||
|
||
/** | ||
* Get the number of machines running in the [`MaybenotFramework`] instance. | ||
* | ||
* # Safety | ||
* - `this` must have been created by [`maybenot_start`]. | ||
*/ | ||
uintptr_t maybenot_num_machines(struct MaybenotFramework *this_); | ||
|
||
/** | ||
* Stop a running [`MaybenotFramework`] instance. This will free the maybenot pointer. | ||
* | ||
* # Safety | ||
* - `this` MUST have been created by [`maybenot_start`]. | ||
* - `this` MUST NOT be used after it has been passed to [`maybenot_stop`]. | ||
*/ | ||
void maybenot_stop(struct MaybenotFramework *this_); | ||
|
||
/** | ||
* Feed events to the [`MaybenotFramework`] instance. | ||
* | ||
* This may generate [super::MaybenotAction]s that will be written to `actions_out`. | ||
* The number of actions will be written to `num_actions_out`. | ||
* | ||
* # Safety | ||
* - `this` MUST have been created by [`maybenot_start`]. | ||
* - `events` MUST be a valid pointer to an array of size `num_events`. | ||
* - `actions_out` MUST have capacity for [`maybenot_num_machines`] items of size | ||
* `sizeof(MaybenotAction)` bytes. | ||
* - `num_actions_out` MUST be a valid pointer where a 64bit int can be written. | ||
*/ | ||
MaybenotResult maybenot_on_events(struct MaybenotFramework *this_, | ||
const struct MaybenotEvent *events, | ||
uintptr_t num_events, | ||
struct MaybenotAction *actions_out, | ||
uintptr_t *num_actions_out); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/// An FFI friendly result error code type. | ||
#[repr(u32)] | ||
#[derive(Debug, Clone, Copy)] | ||
pub enum MaybenotResult { | ||
/// Operation completed successfully | ||
Ok = 0, | ||
|
||
/// The machine string wasn't valid UTF-8 | ||
MachineStringNotUtf8 = 1, | ||
|
||
/// Failed to parse machine string | ||
InvalidMachineString = 2, | ||
|
||
/// Failed to start framework | ||
StartFramework = 3, | ||
|
||
/// A null pointer was encountered | ||
NullPointer = 4, | ||
} | ||
|
||
impl<T> From<Result<T, MaybenotResult>> for MaybenotResult { | ||
fn from(result: Result<T, MaybenotResult>) -> Self { | ||
result.map(|_| MaybenotResult::Ok).unwrap_or_else(|err| err) | ||
} | ||
} |
Oops, something went wrong.