mirror of
https://github.com/cjdelisle/cjdns
synced 2025-10-06 00:32:50 +02:00
Ability to get current state of TUN and UDP worker threads
This commit is contained in:
38
Cargo.lock
generated
38
Cargo.lock
generated
@@ -165,16 +165,6 @@ version = "0.21.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
|
||||
|
||||
[[package]]
|
||||
name = "bendy"
|
||||
version = "0.3.2"
|
||||
source = "git+https://github.com/cjdelisle/bendy-cjdns?tag=v0.3.2-cjdns#21849683c9e9b83b8d217d044c1da78ee573926b"
|
||||
dependencies = [
|
||||
"failure",
|
||||
"serde",
|
||||
"serde_bytes",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bendy"
|
||||
version = "0.3.2"
|
||||
@@ -344,7 +334,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "cjdns"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/cjdelisle/cjdns-route-server?rev=4925a6cd65dc0c2186889363e0bb62182c5d83c5#4925a6cd65dc0c2186889363e0bb62182c5d83c5"
|
||||
source = "git+https://github.com/cjdelisle/cjdns-route-server?rev=d19d5f03c6336f0ae637694968a40e511f3882eb#d19d5f03c6336f0ae637694968a40e511f3882eb"
|
||||
dependencies = [
|
||||
"cjdns-admin",
|
||||
"cjdns-ann",
|
||||
@@ -362,7 +352,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "cjdns-admin"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/cjdelisle/cjdns-route-server?rev=4925a6cd65dc0c2186889363e0bb62182c5d83c5#4925a6cd65dc0c2186889363e0bb62182c5d83c5"
|
||||
source = "git+https://github.com/cjdelisle/cjdns-route-server?rev=d19d5f03c6336f0ae637694968a40e511f3882eb#d19d5f03c6336f0ae637694968a40e511f3882eb"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cjdns-bencode",
|
||||
@@ -380,7 +370,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "cjdns-ann"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/cjdelisle/cjdns-route-server?rev=4925a6cd65dc0c2186889363e0bb62182c5d83c5#4925a6cd65dc0c2186889363e0bb62182c5d83c5"
|
||||
source = "git+https://github.com/cjdelisle/cjdns-route-server?rev=d19d5f03c6336f0ae637694968a40e511f3882eb#d19d5f03c6336f0ae637694968a40e511f3882eb"
|
||||
dependencies = [
|
||||
"cjdns-bytes",
|
||||
"cjdns-core",
|
||||
@@ -395,9 +385,9 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "cjdns-bencode"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/cjdelisle/cjdns-route-server?rev=4925a6cd65dc0c2186889363e0bb62182c5d83c5#4925a6cd65dc0c2186889363e0bb62182c5d83c5"
|
||||
source = "git+https://github.com/cjdelisle/cjdns-route-server?rev=d19d5f03c6336f0ae637694968a40e511f3882eb#d19d5f03c6336f0ae637694968a40e511f3882eb"
|
||||
dependencies = [
|
||||
"bendy 0.3.2 (git+https://github.com/CJDNS-Development-Team/bendy-cjdns?tag=v0.3.2-cjdns)",
|
||||
"bendy",
|
||||
"hex",
|
||||
"serde",
|
||||
]
|
||||
@@ -405,7 +395,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "cjdns-bytes"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/cjdelisle/cjdns-route-server?rev=4925a6cd65dc0c2186889363e0bb62182c5d83c5#4925a6cd65dc0c2186889363e0bb62182c5d83c5"
|
||||
source = "git+https://github.com/cjdelisle/cjdns-route-server?rev=d19d5f03c6336f0ae637694968a40e511f3882eb#d19d5f03c6336f0ae637694968a40e511f3882eb"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64 0.21.7",
|
||||
@@ -417,7 +407,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "cjdns-core"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/cjdelisle/cjdns-route-server?rev=4925a6cd65dc0c2186889363e0bb62182c5d83c5#4925a6cd65dc0c2186889363e0bb62182c5d83c5"
|
||||
source = "git+https://github.com/cjdelisle/cjdns-route-server?rev=d19d5f03c6336f0ae637694968a40e511f3882eb#d19d5f03c6336f0ae637694968a40e511f3882eb"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"regex",
|
||||
@@ -428,7 +418,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "cjdns-crypto"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/cjdelisle/cjdns-route-server?rev=4925a6cd65dc0c2186889363e0bb62182c5d83c5#4925a6cd65dc0c2186889363e0bb62182c5d83c5"
|
||||
source = "git+https://github.com/cjdelisle/cjdns-route-server?rev=d19d5f03c6336f0ae637694968a40e511f3882eb#d19d5f03c6336f0ae637694968a40e511f3882eb"
|
||||
dependencies = [
|
||||
"ed25519",
|
||||
"libsodium-sys",
|
||||
@@ -439,7 +429,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "cjdns-ctrl"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/cjdelisle/cjdns-route-server?rev=4925a6cd65dc0c2186889363e0bb62182c5d83c5#4925a6cd65dc0c2186889363e0bb62182c5d83c5"
|
||||
source = "git+https://github.com/cjdelisle/cjdns-route-server?rev=d19d5f03c6336f0ae637694968a40e511f3882eb#d19d5f03c6336f0ae637694968a40e511f3882eb"
|
||||
dependencies = [
|
||||
"cjdns-bytes",
|
||||
"cjdns-core",
|
||||
@@ -452,7 +442,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "cjdns-hdr"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/cjdelisle/cjdns-route-server?rev=4925a6cd65dc0c2186889363e0bb62182c5d83c5#4925a6cd65dc0c2186889363e0bb62182c5d83c5"
|
||||
source = "git+https://github.com/cjdelisle/cjdns-route-server?rev=d19d5f03c6336f0ae637694968a40e511f3882eb#d19d5f03c6336f0ae637694968a40e511f3882eb"
|
||||
dependencies = [
|
||||
"cjdns-bytes",
|
||||
"cjdns-core",
|
||||
@@ -463,7 +453,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "cjdns-keys"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/cjdelisle/cjdns-route-server?rev=4925a6cd65dc0c2186889363e0bb62182c5d83c5#4925a6cd65dc0c2186889363e0bb62182c5d83c5"
|
||||
source = "git+https://github.com/cjdelisle/cjdns-route-server?rev=d19d5f03c6336f0ae637694968a40e511f3882eb#d19d5f03c6336f0ae637694968a40e511f3882eb"
|
||||
dependencies = [
|
||||
"cjdns-crypto",
|
||||
"data-encoding",
|
||||
@@ -477,7 +467,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "cjdns-sniff"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/cjdelisle/cjdns-route-server?rev=4925a6cd65dc0c2186889363e0bb62182c5d83c5#4925a6cd65dc0c2186889363e0bb62182c5d83c5"
|
||||
source = "git+https://github.com/cjdelisle/cjdns-route-server?rev=d19d5f03c6336f0ae637694968a40e511f3882eb#d19d5f03c6336f0ae637694968a40e511f3882eb"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cjdns-admin",
|
||||
@@ -501,7 +491,6 @@ dependencies = [
|
||||
"anyhow",
|
||||
"async-recursion",
|
||||
"async-trait",
|
||||
"bendy 0.3.2 (git+https://github.com/cjdelisle/bendy-cjdns?tag=v0.3.2-cjdns)",
|
||||
"bindgen",
|
||||
"boringtun",
|
||||
"byteorder",
|
||||
@@ -518,6 +507,7 @@ dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"num_cpus",
|
||||
"num_enum",
|
||||
"once_cell",
|
||||
"parking_lot 0.12.3",
|
||||
"pnet",
|
||||
@@ -1255,7 +1245,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "netchecksum"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/cjdelisle/cjdns-route-server?rev=4925a6cd65dc0c2186889363e0bb62182c5d83c5#4925a6cd65dc0c2186889363e0bb62182c5d83c5"
|
||||
source = "git+https://github.com/cjdelisle/cjdns-route-server?rev=d19d5f03c6336f0ae637694968a40e511f3882eb#d19d5f03c6336f0ae637694968a40e511f3882eb"
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
|
16
Cargo.toml
16
Cargo.toml
@@ -14,13 +14,12 @@ panic = "unwind"
|
||||
opt-level = 2
|
||||
|
||||
[workspace.dependencies]
|
||||
cjdns = { git = "https://github.com/cjdelisle/cjdns-route-server", rev = "4925a6cd65dc0c2186889363e0bb62182c5d83c5", version = "0.1.0" }
|
||||
cjdns-admin = { git = "https://github.com/cjdelisle/cjdns-route-server", rev = "4925a6cd65dc0c2186889363e0bb62182c5d83c5", version = "0.1.0" }
|
||||
cjdns-crypto = { git = "https://github.com/cjdelisle/cjdns-route-server", rev = "4925a6cd65dc0c2186889363e0bb62182c5d83c5", version = "0.1.0" }
|
||||
cjdns-keys = { git = "https://github.com/cjdelisle/cjdns-route-server", rev = "4925a6cd65dc0c2186889363e0bb62182c5d83c5", version = "0.1.0" }
|
||||
cjdns-bytes = { git = "https://github.com/cjdelisle/cjdns-route-server", rev = "4925a6cd65dc0c2186889363e0bb62182c5d83c5", version = "0.1.0" }
|
||||
cjdns-bencode = { git = "https://github.com/cjdelisle/cjdns-route-server", rev = "4925a6cd65dc0c2186889363e0bb62182c5d83c5", version = "0.1.0" }
|
||||
bendy = { git = "https://github.com/cjdelisle/bendy-cjdns", tag = "v0.3.2-cjdns", features = ["std", "serde"] }
|
||||
cjdns = { git = "https://github.com/cjdelisle/cjdns-route-server", rev = "d19d5f03c6336f0ae637694968a40e511f3882eb", version = "0.1.0" }
|
||||
cjdns-admin = { git = "https://github.com/cjdelisle/cjdns-route-server", rev = "d19d5f03c6336f0ae637694968a40e511f3882eb", version = "0.1.0" }
|
||||
cjdns-crypto = { git = "https://github.com/cjdelisle/cjdns-route-server", rev = "d19d5f03c6336f0ae637694968a40e511f3882eb", version = "0.1.0" }
|
||||
cjdns-keys = { git = "https://github.com/cjdelisle/cjdns-route-server", rev = "d19d5f03c6336f0ae637694968a40e511f3882eb", version = "0.1.0" }
|
||||
cjdns-bytes = { git = "https://github.com/cjdelisle/cjdns-route-server", rev = "d19d5f03c6336f0ae637694968a40e511f3882eb", version = "0.1.0" }
|
||||
cjdns-bencode = { git = "https://github.com/cjdelisle/cjdns-route-server", rev = "d19d5f03c6336f0ae637694968a40e511f3882eb", version = "0.1.0" }
|
||||
sodiumoxide = { git = "https://github.com/cjdelisle/sodiumoxide", rev = "9f6a18d40a4db253edfebac9f2ce5c22d09b1f47", version = "0.2", default-features = false, features = ["std"] }
|
||||
clap = { version = "4", features = ["derive"] }
|
||||
const_format = "0.2"
|
||||
@@ -50,4 +49,5 @@ cbindgen = { version = "0.16" }
|
||||
bindgen = { version = "0.55" }
|
||||
byteorder = "1.5"
|
||||
trust-dns-resolver = "0.23.2"
|
||||
ipnetwork = "0.20"
|
||||
ipnetwork = "0.20"
|
||||
num_enum = "0.7"
|
@@ -99,13 +99,21 @@
|
||||
/** The default MTU, assuming the external MTU is 1492 (common for PPPoE DSL) */
|
||||
#define DEFAULT_MTU ( 1492 - WORST_CASE_OVERHEAD )
|
||||
|
||||
static void adminPing(Dict* input, void* vadmin, String* txid, struct Allocator* requestAlloc)
|
||||
static void adminPing(
|
||||
Gcc_UNUSED Dict* input,
|
||||
void* vadmin,
|
||||
String* txid,
|
||||
Gcc_UNUSED struct Allocator* requestAlloc)
|
||||
{
|
||||
Dict d = Dict_CONST(String_CONST("q"), String_OBJ(String_CONST("pong")), NULL);
|
||||
Admin_sendMessage(&d, txid, (struct Admin*) vadmin);
|
||||
}
|
||||
|
||||
static void adminPid(Dict* input, void* vadmin, String* txid, struct Allocator* requestAlloc)
|
||||
static void adminPid(
|
||||
Gcc_UNUSED Dict* input,
|
||||
void* vadmin,
|
||||
String* txid,
|
||||
Gcc_UNUSED struct Allocator* requestAlloc)
|
||||
{
|
||||
int pid = getpid();
|
||||
Dict d = Dict_CONST(String_CONST("pid"), Int_OBJ(pid), NULL);
|
||||
@@ -123,7 +131,8 @@ struct Context
|
||||
struct EncodingScheme* encodingScheme;
|
||||
struct GlobalConfig* globalConf;
|
||||
|
||||
struct Iface* tunDevice;
|
||||
Iface_t* tunIface;
|
||||
TUNInterface_t* tun;
|
||||
struct Allocator* tunAlloc;
|
||||
|
||||
Identity
|
||||
@@ -135,7 +144,11 @@ static void shutdown(void* vcontext)
|
||||
Allocator_free(context->alloc);
|
||||
}
|
||||
|
||||
static void adminExit(Dict* input, void* vcontext, String* txid, struct Allocator* requestAlloc)
|
||||
static void adminExit(
|
||||
Gcc_UNUSED Dict* input,
|
||||
void* vcontext,
|
||||
String* txid,
|
||||
Gcc_UNUSED struct Allocator* requestAlloc)
|
||||
{
|
||||
struct Context* context = Identity_check((struct Context*) vcontext);
|
||||
Log_info(context->logger, "Got request to exit");
|
||||
@@ -154,16 +167,15 @@ static void sendResponse(String* error,
|
||||
Admin_sendMessage(output, txid, admin);
|
||||
}
|
||||
|
||||
static Err_DEFUN initSocket2(String* socketFullPath,
|
||||
struct Context* ctx,
|
||||
uint8_t addressPrefix)
|
||||
static Err_DEFUN initSocket2(String* socketFullPath, struct Context* ctx)
|
||||
{
|
||||
Log_debug(ctx->logger, "Initializing socket: %s;", socketFullPath->bytes);
|
||||
|
||||
if (ctx->tunDevice) {
|
||||
Iface_unplumb(ctx->tunDevice, &ctx->nc->tunAdapt->tunIf);
|
||||
if (ctx->tunIface) {
|
||||
Iface_unplumb(ctx->tunIface, &ctx->nc->tunAdapt->tunIf);
|
||||
Allocator_free(ctx->tunAlloc);
|
||||
ctx->tunDevice = NULL;
|
||||
ctx->tunIface = NULL;
|
||||
ctx->tun = NULL;
|
||||
}
|
||||
ctx->tunAlloc = Allocator_child(ctx->alloc);
|
||||
|
||||
@@ -172,8 +184,8 @@ static Err_DEFUN initSocket2(String* socketFullPath,
|
||||
struct SocketWrapper* sw = SocketWrapper_new(ctx->tunAlloc, ctx->logger);
|
||||
Iface_plumb(&sw->externalIf, rawSocketIf);
|
||||
|
||||
ctx->tunDevice = &sw->internalIf;
|
||||
Iface_plumb(ctx->tunDevice, &ctx->nc->tunAdapt->tunIf);
|
||||
ctx->tunIface = &sw->internalIf;
|
||||
Iface_plumb(ctx->tunIface, &ctx->nc->tunAdapt->tunIf);
|
||||
|
||||
Err(SocketWrapper_addAddress(
|
||||
&sw->externalIf, ctx->nc->myAddress->ip6.bytes, ctx->logger, ctx->alloc));
|
||||
@@ -192,22 +204,22 @@ static Err_DEFUN initTunnel2(String* desiredDeviceName,
|
||||
char assignedTunName[TUNInterface_IFNAMSIZ];
|
||||
char* desiredName = (desiredDeviceName) ? desiredDeviceName->bytes : NULL;
|
||||
|
||||
if (ctx->tunDevice) {
|
||||
Iface_unplumb(&ctx->nc->tunAdapt->tunIf, ctx->tunDevice);
|
||||
if (ctx->tunIface) {
|
||||
Iface_unplumb(&ctx->nc->tunAdapt->tunIf, ctx->tunIface);
|
||||
Allocator_free(ctx->tunAlloc);
|
||||
ctx->tunDevice = NULL;
|
||||
ctx->tunIface = NULL;
|
||||
ctx->tun = NULL;
|
||||
}
|
||||
ctx->tunAlloc = Allocator_child(ctx->alloc);
|
||||
Err(TUNInterface_new(
|
||||
&ctx->tunDevice,
|
||||
&ctx->tun,
|
||||
desiredName,
|
||||
assignedTunName,
|
||||
0,
|
||||
ctx->base,
|
||||
ctx->logger,
|
||||
ctx->tunAlloc));
|
||||
|
||||
Iface_plumb(ctx->tunDevice, &ctx->nc->tunAdapt->tunIf);
|
||||
ctx->tunIface = ctx->tun->iface;
|
||||
Iface_plumb(ctx->tunIface, &ctx->nc->tunAdapt->tunIf);
|
||||
|
||||
GlobalConfig_setTunName(ctx->globalConf, String_CONST(assignedTunName));
|
||||
|
||||
@@ -233,8 +245,8 @@ static void initTunfd(Dict* args, void* vcontext, String* txid, struct Allocator
|
||||
int type = (tuntype) ? *tuntype : TUNMessageType_guess();
|
||||
|
||||
struct Allocator* tunAlloc = Allocator_child(ctx->alloc);
|
||||
Iface_t* socketIf = NULL;
|
||||
RTypes_Error_t* er = Socket_forFd(&socketIf, fileno, Socket_forFd_FRAMES, tunAlloc);
|
||||
TUNInterface_t* tun = NULL;
|
||||
RTypes_Error_t* er = TUNInterface_forFd(&tun, fileno, tunAlloc);
|
||||
if (er) {
|
||||
const char* err = Rffi_printError(er, requestAlloc);
|
||||
Log_debug(ctx->logger, "Failed to create pipe [%s]", err);
|
||||
@@ -243,35 +255,36 @@ static void initTunfd(Dict* args, void* vcontext, String* txid, struct Allocator
|
||||
sendResponse(error, ctx->admin, txid, requestAlloc);
|
||||
return;
|
||||
}
|
||||
struct Iface* iface = NULL;
|
||||
Iface_t* iface = tun->iface;
|
||||
if (type == TUNMessageType_NONE) {
|
||||
RTypes_IfWrapper_t aw = Rffi_android_create(tunAlloc);
|
||||
Iface_plumb(aw.external, socketIf);
|
||||
Iface_plumb(aw.external, tun->iface);
|
||||
iface = aw.internal;
|
||||
} else {
|
||||
iface = socketIf;
|
||||
}
|
||||
|
||||
if (ctx->tunDevice) {
|
||||
Iface_unplumb(&ctx->nc->tunAdapt->tunIf, ctx->tunDevice);
|
||||
if (ctx->tunIface) {
|
||||
Iface_unplumb(&ctx->nc->tunAdapt->tunIf, ctx->tunIface);
|
||||
Allocator_free(ctx->tunAlloc);
|
||||
ctx->tunDevice = NULL;
|
||||
ctx->tunIface = NULL;
|
||||
ctx->tun = NULL;
|
||||
}
|
||||
Assert_true(!ctx->nc->tunAdapt->tunIf.connectedIf);
|
||||
ctx->tunAlloc = tunAlloc;
|
||||
ctx->tunDevice = iface;
|
||||
Iface_plumb(ctx->tunDevice, &ctx->nc->tunAdapt->tunIf);
|
||||
ctx->tun = tun;
|
||||
ctx->tunIface = iface;
|
||||
Iface_plumb(iface, &ctx->nc->tunAdapt->tunIf);
|
||||
|
||||
sendResponse(String_CONST("none"), ctx->admin, txid, requestAlloc);
|
||||
}
|
||||
|
||||
static void stopTun(Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc)
|
||||
static void stopTun(Gcc_UNUSED Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc)
|
||||
{
|
||||
struct Context* ctx = Identity_check((struct Context*) vcontext);
|
||||
if (ctx->tunDevice) {
|
||||
Iface_unplumb(&ctx->nc->tunAdapt->tunIf, ctx->tunDevice);
|
||||
if (ctx->tunIface) {
|
||||
Iface_unplumb(&ctx->nc->tunAdapt->tunIf, ctx->tunIface);
|
||||
Allocator_free(ctx->tunAlloc);
|
||||
ctx->tunDevice = NULL;
|
||||
ctx->tunIface = NULL;
|
||||
ctx->tun = NULL;
|
||||
sendResponse(String_new("none", requestAlloc), ctx->admin, txid, requestAlloc);
|
||||
} else {
|
||||
sendResponse(
|
||||
@@ -282,6 +295,34 @@ static void stopTun(Dict* args, void* vcontext, String* txid, struct Allocator*
|
||||
}
|
||||
}
|
||||
|
||||
static void tunWorkers(Dict* Gcc_UNUSED args, void* vcontext, String* txid, struct Allocator* requestAlloc)
|
||||
{
|
||||
struct Context* ctx = Identity_check((struct Context*) vcontext);
|
||||
if (ctx->tun) {
|
||||
Object_t* workers = NULL;
|
||||
RTypes_Error_t* err = TUNInterface_workerStates(&workers, ctx->tun, requestAlloc);
|
||||
if (err) {
|
||||
char* error = Rffi_printError(err, requestAlloc);
|
||||
sendResponse(
|
||||
String_new(error, requestAlloc),
|
||||
ctx->admin,
|
||||
txid,
|
||||
requestAlloc);
|
||||
} else {
|
||||
Dict* output = Dict_new(requestAlloc);
|
||||
Dict_putStringCC(output, "error", "none", requestAlloc);
|
||||
Dict_putObject(output, String_CONST("workers"), workers, requestAlloc);
|
||||
Admin_sendMessage(output, txid, ctx->admin);
|
||||
}
|
||||
} else {
|
||||
sendResponse(
|
||||
String_new("TUN device missing or does not use workers", requestAlloc),
|
||||
ctx->admin,
|
||||
txid,
|
||||
requestAlloc);
|
||||
}
|
||||
}
|
||||
|
||||
static void initTunnel(Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc)
|
||||
{
|
||||
struct Context* const ctx = Identity_check((struct Context*) vcontext);
|
||||
@@ -301,7 +342,7 @@ static void initSocket(Dict* args, void* vcontext, String* txid, struct Allocato
|
||||
{
|
||||
struct Context* const ctx = Identity_check((struct Context*) vcontext);
|
||||
String* socketFullPath = Dict_getStringC(args, "socketFullPath");
|
||||
RTypes_Error_t* err = initSocket2(socketFullPath, ctx, AddressCalc_ADDRESS_PREFIX_BITS);
|
||||
RTypes_Error_t* err = initSocket2(socketFullPath, ctx);
|
||||
if (err) {
|
||||
String* error = String_printf(requestAlloc, "Failed to configure socket [%s]",
|
||||
Rffi_printError(err, requestAlloc));
|
||||
@@ -311,7 +352,7 @@ static void initSocket(Dict* args, void* vcontext, String* txid, struct Allocato
|
||||
sendResponse(String_CONST("none"), ctx->admin, txid, requestAlloc);
|
||||
}
|
||||
|
||||
static void nodeInfo(Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc)
|
||||
static void nodeInfo(Gcc_UNUSED Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc)
|
||||
{
|
||||
struct Context* const ctx = Identity_check((struct Context*) vcontext);
|
||||
String* myAddr = Address_toStringKey(ctx->nc->myAddress, requestAlloc);
|
||||
@@ -387,7 +428,7 @@ Err_DEFUN Core_init(struct Allocator* alloc,
|
||||
ReachabilityCollector_admin_register(spf->rc, admin, alloc);
|
||||
|
||||
AuthorizedPasswords_init(admin, nc->ca, alloc);
|
||||
Admin_registerFunction("ping", adminPing, admin, false, NULL, admin);
|
||||
Admin_registerFunctionNoArgs("ping", adminPing, admin, false, admin);
|
||||
if (!noSec) {
|
||||
Security_admin_register(alloc, logger, sec, admin);
|
||||
}
|
||||
@@ -407,9 +448,9 @@ Err_DEFUN Core_init(struct Allocator* alloc,
|
||||
ctx->encodingScheme = encodingScheme;
|
||||
ctx->globalConf = globalConf;
|
||||
|
||||
Admin_registerFunction("Core_exit", adminExit, ctx, true, NULL, admin);
|
||||
Admin_registerFunctionNoArgs("Core_exit", adminExit, ctx, true, admin);
|
||||
|
||||
Admin_registerFunction("Core_pid", adminPid, admin, false, NULL, admin);
|
||||
Admin_registerFunctionNoArgs("Core_pid", adminPid, admin, false, admin);
|
||||
|
||||
Admin_registerFunction("Core_initTunnel", initTunnel, ctx, true,
|
||||
((struct Admin_FunctionArg[]) {
|
||||
@@ -422,15 +463,17 @@ Err_DEFUN Core_init(struct Allocator* alloc,
|
||||
{ .name = "type", .required = 0, .type = "Int" }
|
||||
}), admin);
|
||||
|
||||
Admin_registerFunction("Core_stopTun", stopTun, ctx, true, NULL, admin);
|
||||
Admin_registerFunctionNoArgs("Core_stopTun", stopTun, ctx, true, admin);
|
||||
|
||||
Admin_registerFunction("Core_nodeInfo", nodeInfo, ctx, false, NULL, admin);
|
||||
Admin_registerFunctionNoArgs("Core_nodeInfo", nodeInfo, ctx, false, admin);
|
||||
|
||||
Admin_registerFunction("Core_initSocket", initSocket, ctx, true,
|
||||
((struct Admin_FunctionArg[]) {
|
||||
{ .name = "socketFullPath", .required = 1, .type = "String" },
|
||||
{ .name = "socketAttemptToCreate", .required = 0, .type = "Int" }
|
||||
}), admin);
|
||||
|
||||
Admin_registerFunctionNoArgs("Core_tunWorkers", tunWorkers, ctx, true, admin);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -502,7 +545,7 @@ int Core_main(int argc, char** argv)
|
||||
|
||||
// --------------------- Bind Admin UDP --------------------- //
|
||||
struct UDPAddrIface* udpAdmin = NULL;
|
||||
Err_assert(UDPAddrIface_new(&udpAdmin, eventBase, &bindAddr.addr, alloc, logger));
|
||||
Err_assert(UDPAddrIface_new(&udpAdmin, &bindAddr.addr, alloc));
|
||||
|
||||
// ---- Setup a muxer so we can get admin from socket or UDP ---- //
|
||||
struct AddrIfaceMuxer* muxer = AddrIfaceMuxer_new(logger, alloc);
|
||||
|
10
benc/Dict.c
10
benc/Dict.c
@@ -110,7 +110,7 @@ Dict* Dict_new(struct Allocator* allocator)
|
||||
* Otherwise: if the key already exists in the dictionary then the value which was
|
||||
* displaced by the put, if not then NULL.
|
||||
*/
|
||||
static Object* putObject(Dict* dictionary,
|
||||
Object* Dict_putObject(Dict* dictionary,
|
||||
const String* key,
|
||||
Object* value,
|
||||
struct Allocator* allocator)
|
||||
@@ -148,7 +148,7 @@ Object* Dict_putInt(Dict* dictionary,
|
||||
.type = Object_INTEGER,
|
||||
.as.number = value
|
||||
}));
|
||||
return putObject(dictionary, key, v, allocator);
|
||||
return Dict_putObject(dictionary, key, v, allocator);
|
||||
}
|
||||
|
||||
/** @see Object.h */
|
||||
@@ -164,7 +164,7 @@ Object* Dict_putString(Dict* dictionary,
|
||||
.type = Object_STRING,
|
||||
.as.string = value
|
||||
}));
|
||||
return putObject(dictionary, key, v, allocator);
|
||||
return Dict_putObject(dictionary, key, v, allocator);
|
||||
}
|
||||
|
||||
/** @see Object.h */
|
||||
@@ -181,7 +181,7 @@ Object* Dict_putList(Dict* dictionary,
|
||||
/* Lists and dictionaries are double pointers so they have to be loaded. */
|
||||
.as.list = value
|
||||
}));
|
||||
return putObject(dictionary, key, v, allocator);
|
||||
return Dict_putObject(dictionary, key, v, allocator);
|
||||
}
|
||||
|
||||
Object* Dict_putDict(Dict* dictionary,
|
||||
@@ -197,7 +197,7 @@ Object* Dict_putDict(Dict* dictionary,
|
||||
/* Lists and dictionaries are double pointers so they have to be loaded. */
|
||||
.as.dictionary = value
|
||||
}));
|
||||
return putObject(dictionary, key, v, allocator);
|
||||
return Dict_putObject(dictionary, key, v, allocator);
|
||||
}
|
||||
|
||||
/** @see Object.h */
|
||||
|
@@ -106,6 +106,11 @@ List* Dict_getList(const Dict* dictionary, const String* key);
|
||||
|
||||
/*----------------------- Dictionary Put Functions -----------------------*/
|
||||
|
||||
Object* Dict_putObject(Dict* dictionary,
|
||||
const String* key,
|
||||
Object* value,
|
||||
struct Allocator* allocator);
|
||||
|
||||
/**
|
||||
* Insert an integer into a dictionary.
|
||||
*
|
||||
|
@@ -715,7 +715,7 @@ void Configurator_config(Dict* config,
|
||||
{
|
||||
struct Allocator* tempAlloc = Allocator_child(alloc);
|
||||
struct UDPAddrIface* udp = NULL;
|
||||
Err_assert(UDPAddrIface_new(&udp, eventBase, NULL, alloc, logger));
|
||||
Err_assert(UDPAddrIface_new(&udp, NULL, alloc));
|
||||
struct AdminClient* client =
|
||||
AdminClient_new(&udp->generic, sockAddr, adminPassword, eventBase, logger, tempAlloc);
|
||||
|
||||
|
@@ -493,7 +493,7 @@ static Err_DEFUN checkRunningInstance(struct Allocator* allocator,
|
||||
}
|
||||
|
||||
struct UDPAddrIface* udp = NULL;
|
||||
RTypes_Error_t* err = UDPAddrIface_new(&udp, base, NULL, alloc, logger);
|
||||
RTypes_Error_t* err = UDPAddrIface_new(&udp, NULL, alloc);
|
||||
if (err) {
|
||||
Allocator_free(alloc);
|
||||
return err;
|
||||
|
@@ -221,7 +221,7 @@ Err_DEFUN UDPInterface_new(
|
||||
}
|
||||
|
||||
struct UDPAddrIface* uai = NULL;
|
||||
Err(UDPAddrIface_new(&uai, eventBase, bindAddr, alloc, logger));
|
||||
Err(UDPAddrIface_new(&uai, bindAddr, alloc));
|
||||
|
||||
uint16_t commPort = Sockaddr_getPort(uai->generic.addr);
|
||||
|
||||
@@ -245,7 +245,7 @@ Err_DEFUN UDPInterface_new(
|
||||
struct Sockaddr* bcastAddr = Sockaddr_clone(bindAddr, alloc);
|
||||
Sockaddr_setPort(bcastAddr, beaconPort);
|
||||
struct UDPAddrIface* bcast = NULL;
|
||||
Err(UDPAddrIface_new(&bcast, eventBase, bcastAddr, alloc, logger));
|
||||
Err(UDPAddrIface_new(&bcast, bcastAddr, alloc));
|
||||
UDPAddrIface_setBroadcast(bcast, 1);
|
||||
Iface_plumb(bcast->generic.iface, &context->bcastSock);
|
||||
context->bcastIf = bcast;
|
||||
@@ -308,6 +308,15 @@ List* UDPInterface_getBroadcastAddrs(struct UDPInterface* udpif, struct Allocato
|
||||
return out;
|
||||
}
|
||||
|
||||
Err_DEFUN UDPInterface_workerStates(
|
||||
Object_t** out,
|
||||
struct UDPInterface* udpif,
|
||||
Allocator_t* alloc)
|
||||
{
|
||||
struct UDPInterface_pvt* ctx = Identity_check((struct UDPInterface_pvt*) udpif);
|
||||
return UDPAddrIface_workerStates(out, ctx->commIf, alloc);
|
||||
}
|
||||
|
||||
int UDPInterface_setDSCP(struct UDPInterface* udpif, uint8_t dscp)
|
||||
{
|
||||
struct UDPInterface_pvt* ctx = Identity_check((struct UDPInterface_pvt*) udpif);
|
||||
|
@@ -116,4 +116,9 @@ int UDPInterface_setDSCP(struct UDPInterface* udpif, uint8_t dscp);
|
||||
|
||||
int UDPInterface_getFd(struct UDPInterface* udpif);
|
||||
|
||||
Err_DEFUN UDPInterface_workerStates(
|
||||
Object_t** out,
|
||||
struct UDPInterface* udpif,
|
||||
Allocator_t* alloc);
|
||||
|
||||
#endif
|
@@ -231,7 +231,7 @@ static void newInterface(Dict* args, void* vcontext, String* txid, struct Alloca
|
||||
newInterface2(ctx, &addr.addr, dscp, txid, requestAlloc, beaconPort);
|
||||
}
|
||||
|
||||
static void listDevices(Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc)
|
||||
static void listDevices(Gcc_UNUSED Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc)
|
||||
{
|
||||
struct Context* ctx = Identity_check((struct Context*) vcontext);
|
||||
Dict* out = Dict_new(requestAlloc);
|
||||
@@ -338,6 +338,22 @@ static void getFd(Dict* args, void* vcontext, String* txid, struct Allocator* re
|
||||
Admin_sendMessage(out, txid, ctx->admin);
|
||||
}
|
||||
|
||||
static void workerStates(Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc) {
|
||||
struct Context* ctx = Identity_check((struct Context*) vcontext);
|
||||
struct UDPInterface* udpif = getIface(ctx, args, txid, requestAlloc, NULL);
|
||||
Object_t* ws = NULL;
|
||||
RTypes_Error_t* err = UDPInterface_workerStates(&ws, udpif, requestAlloc);
|
||||
Dict* out = Dict_new(requestAlloc);
|
||||
if (err) {
|
||||
char* ers = Rffi_printError(err, requestAlloc);
|
||||
Dict_putStringCC(out, "error", ers, requestAlloc);
|
||||
} else {
|
||||
Dict_putStringCC(out, "error", "none", requestAlloc);
|
||||
Dict_putObject(out, String_CONST("workers"), ws, requestAlloc);
|
||||
}
|
||||
Admin_sendMessage(out, txid, ctx->admin);
|
||||
}
|
||||
|
||||
void UDPInterface_admin_register(EventBase_t* base,
|
||||
struct Allocator* alloc,
|
||||
struct Log* logger,
|
||||
@@ -374,7 +390,7 @@ void UDPInterface_admin_register(EventBase_t* base,
|
||||
{ .name = "version", .required = 0, .type = "Int" },
|
||||
}), admin);
|
||||
|
||||
Admin_registerFunction("UDPInterface_listDevices", listDevices, ctx, true, NULL, admin);
|
||||
Admin_registerFunctionNoArgs("UDPInterface_listDevices", listDevices, ctx, true, admin);
|
||||
|
||||
Admin_registerFunction("UDPInterface_setBroadcastDevices", setBroadcastDevices, ctx, true,
|
||||
((struct Admin_FunctionArg[]) {
|
||||
@@ -402,4 +418,9 @@ void UDPInterface_admin_register(EventBase_t* base,
|
||||
((struct Admin_FunctionArg[]) {
|
||||
{ .name = "interfaceNumber", .required = 0, .type = "Int" },
|
||||
}), admin);
|
||||
|
||||
Admin_registerFunction("UDPInterface_workerStates", workerStates, ctx, true,
|
||||
((struct Admin_FunctionArg[]) {
|
||||
{ .name = "interfaceNumber", .required = 0, .type = "Int" },
|
||||
}), admin);
|
||||
}
|
||||
|
@@ -1,120 +0,0 @@
|
||||
/* vim: set expandtab ts=4 sw=4: */
|
||||
/*
|
||||
* You may redistribute this program and/or modify it under the terms of
|
||||
* the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "interface/tuntap/TUNMessageType.h"
|
||||
#include "interface/tuntap/ARPServer.h"
|
||||
#include "interface/Iface.h"
|
||||
#include "memory/Allocator.h"
|
||||
#include "util/Bits.h"
|
||||
#include "util/log/Log.h"
|
||||
#include "util/Identity.h"
|
||||
#include "util/Endian.h"
|
||||
#include "wire/ARPHeader.h"
|
||||
#include "wire/Ethernet.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
struct ARPServer_pvt
|
||||
{
|
||||
struct ARPServer pub;
|
||||
struct Iface external;
|
||||
struct Log* log;
|
||||
uint8_t localMac[Ethernet_ADDRLEN];
|
||||
Identity
|
||||
};
|
||||
|
||||
static bool isValidARP(Message_t* msg)
|
||||
{
|
||||
struct ARPHeader_6_4 arp;
|
||||
Err_assert(Message_epop(msg, &arp, ARPHeader_6_4_SIZE));
|
||||
Err_assert(Message_eshift(msg, ARPHeader_6_4_SIZE)); // Get copy and restore.
|
||||
if (!ARPHeader_isEthIP4(&arp.prefix)) {
|
||||
return false; // not ARP.
|
||||
}
|
||||
if (arp.prefix.operation != ARPHeader_OP_Q) {
|
||||
return false; // Not question.
|
||||
}
|
||||
if (Bits_memcmp(arp.spa, arp.tpa, 4) == 0) {
|
||||
return false; // not really ARP question.
|
||||
}
|
||||
if (Bits_isZero(arp.spa, 4)) {
|
||||
return false; // "I am just checking if this IP is not taken."
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static Iface_DEFUN answerARP(Message_t* msg, struct ARPServer_pvt* as)
|
||||
{
|
||||
struct ARPHeader_6_4 arp;
|
||||
Err(Message_epop(msg, &arp, ARPHeader_6_4_SIZE));
|
||||
if (Message_getLength(msg)) {
|
||||
Log_warn(as->log, "%d extra bytes in ARP, weird", Message_getLength(msg));
|
||||
}
|
||||
// Swap sender with target.
|
||||
// 10 = Eth_Len + IP4_Len
|
||||
uint8_t tmp[10];
|
||||
Bits_memcpy(tmp, arp.sha, 10);
|
||||
Bits_memcpy(arp.sha, arp.tha, 10);
|
||||
Bits_memcpy(arp.tha, tmp, 10);
|
||||
// Set our MAC as source
|
||||
Bits_memcpy(arp.sha, as->localMac, Ethernet_ADDRLEN);
|
||||
// Set answer opcode.
|
||||
arp.prefix.operation = ARPHeader_OP_A;
|
||||
|
||||
Err(Message_epush(msg, &arp, ARPHeader_6_4_SIZE));
|
||||
Err(TUNMessageType_push(msg, Ethernet_TYPE_ARP));
|
||||
|
||||
Log_debug(as->log, "Sending ARP answer.");
|
||||
|
||||
return Iface_next(&as->external, msg);
|
||||
}
|
||||
|
||||
static Iface_DEFUN receiveMessage(Message_t* msg, struct Iface* external)
|
||||
{
|
||||
struct ARPServer_pvt* as = Identity_containerOf(external, struct ARPServer_pvt, external);
|
||||
// Length should be ARP + Ethertype
|
||||
if (Message_getLength(msg) >= ARPHeader_6_4_SIZE + 4) {
|
||||
uint16_t ethertype = -1;
|
||||
Err(TUNMessageType_pop(ðertype, msg));
|
||||
if (ethertype == Ethernet_TYPE_ARP) {
|
||||
if (isValidARP(msg)) {
|
||||
return answerARP(msg, as);
|
||||
}
|
||||
}
|
||||
Err(TUNMessageType_push(msg, ethertype));
|
||||
}
|
||||
return Iface_next(&as->pub.internal, msg);
|
||||
}
|
||||
|
||||
static Iface_DEFUN sendMessage(Message_t* msg, struct Iface* internal)
|
||||
{
|
||||
struct ARPServer_pvt* as = Identity_containerOf(internal, struct ARPServer_pvt, pub.internal);
|
||||
return Iface_next(&as->external, msg);
|
||||
}
|
||||
|
||||
struct ARPServer* ARPServer_new(struct Iface* external,
|
||||
struct Log* log,
|
||||
uint8_t localMac[Ethernet_ADDRLEN],
|
||||
struct Allocator* alloc)
|
||||
{
|
||||
struct ARPServer_pvt* out = Allocator_calloc(alloc, sizeof(struct ARPServer_pvt), 1);
|
||||
Identity_set(out);
|
||||
out->external.send = receiveMessage;
|
||||
Iface_plumb(&out->external, external);
|
||||
out->pub.internal.send = sendMessage;
|
||||
out->log = log;
|
||||
Bits_memcpy(out->localMac, localMac, Ethernet_ADDRLEN);
|
||||
return &out->pub;
|
||||
}
|
||||
|
@@ -1,156 +0,0 @@
|
||||
/* vim: set expandtab ts=4 sw=4: */
|
||||
/*
|
||||
* You may redistribute this program and/or modify it under the terms of
|
||||
* the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "interface/tuntap/TUNMessageType.h"
|
||||
#include "interface/tuntap/NDPServer.h"
|
||||
#include "util/Bits.h"
|
||||
#include "util/Checksum.h"
|
||||
#include "util/Identity.h"
|
||||
#include "wire/Message.h"
|
||||
#include "wire/Ethernet.h"
|
||||
#include "wire/Headers.h"
|
||||
#include "wire/NDPHeader.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
struct NDPServer_pvt
|
||||
{
|
||||
struct NDPServer pub;
|
||||
struct Iface external;
|
||||
struct Log* log;
|
||||
uint8_t localMac[Ethernet_ADDRLEN];
|
||||
Identity
|
||||
};
|
||||
|
||||
#define MULTICAST_ADDR "\xff\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xff\x00\x00\x08"
|
||||
// ff 02 00 00 00 00 00 00 00 00 00 01 ff 00 00 02 870099
|
||||
#define UNICAST_ADDR "\xfe\x80\0\0\0\0\0\0\0\0\0\0\0\0\0\x08"
|
||||
|
||||
//#define UNICAST_ADDR "\xfd\x80\0\0\0\0\0\0\0\0\0\0\0\0\0\x08"
|
||||
|
||||
#define ALL_ROUTERS "\xff\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\x02"
|
||||
|
||||
static bool isNeighborSolicitation(Message_t* msg, struct NDPServer_pvt* ns)
|
||||
{
|
||||
if (Message_getLength(msg) < Headers_IP6Header_SIZE + NDPHeader_NeighborSolicitation_SIZE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
struct Headers_IP6Header* ip6 = (struct Headers_IP6Header*) Message_bytes(msg);
|
||||
struct NDPHeader_NeighborSolicitation* sol = (struct NDPHeader_NeighborSolicitation*) &ip6[1];
|
||||
|
||||
if (sol->oneThirtyFive != 135 || sol->zero != 0) {
|
||||
Log_debug(ns->log, "wrong type/code for neighbor solicitation");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (//Bits_memcmp(ip6->destinationAddr, UNICAST_ADDR, 16) ||
|
||||
Bits_memcmp(ip6->destinationAddr, MULTICAST_ADDR, 13))
|
||||
{
|
||||
Log_debug(ns->log, "wrong address for neighbor solicitation");
|
||||
return false;
|
||||
}
|
||||
|
||||
/*if (Bits_memcmp(sol->targetAddr, UNICAST_ADDR, 16)) {
|
||||
Log_debug(ns->log, "Soliciting the wrong neighbor");
|
||||
return false;
|
||||
}*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static Iface_DEFUN answerNeighborSolicitation(Message_t* msg, struct NDPServer_pvt* ns)
|
||||
{
|
||||
struct Headers_IP6Header ip6;
|
||||
Err(Message_epop(msg, &ip6, Headers_IP6Header_SIZE));
|
||||
struct NDPHeader_NeighborSolicitation sol;
|
||||
Err(Message_epop(msg, &sol, NDPHeader_NeighborSolicitation_SIZE));
|
||||
if (Message_getLength(msg)) {
|
||||
/* Right now we ignore any ICMP options. Windows will send them. */
|
||||
Log_debug(ns->log, "%d extra bytes (ICMP options?) in neighbor solicitation",
|
||||
Message_getLength(msg));
|
||||
}
|
||||
|
||||
struct NDPHeader_MacOpt macOpt = {
|
||||
.type = NDPHeader_MacOpt_type_TARGET,
|
||||
.one = 1
|
||||
};
|
||||
Bits_memcpy(macOpt.mac, ns->localMac, Ethernet_ADDRLEN);
|
||||
Err(Message_epush(msg, &macOpt, sizeof(struct NDPHeader_MacOpt)));
|
||||
|
||||
struct NDPHeader_NeighborAdvert na = {
|
||||
.oneThirtySix = 136,
|
||||
.zero = 0,
|
||||
.checksum = 0,
|
||||
.bits = NDPHeader_NeighborAdvert_bits_ROUTER
|
||||
| NDPHeader_NeighborAdvert_bits_SOLICITED
|
||||
| NDPHeader_NeighborAdvert_bits_OVERRIDE
|
||||
};
|
||||
Bits_memcpy(na.targetAddr, sol.targetAddr, 16);
|
||||
Err(Message_epush(msg, &na, sizeof(struct NDPHeader_NeighborAdvert)));
|
||||
|
||||
Bits_memcpy(ip6.destinationAddr, ip6.sourceAddr, 16);
|
||||
Bits_memcpy(ip6.sourceAddr, sol.targetAddr, 16);
|
||||
ip6.hopLimit = 255;
|
||||
ip6.payloadLength_be = Endian_hostToBigEndian16(Message_getLength(msg));
|
||||
|
||||
struct NDPHeader_RouterAdvert* adv = (struct NDPHeader_RouterAdvert*) Message_bytes(msg);
|
||||
adv->checksum = Checksum_icmp6_be(ip6.sourceAddr, Message_bytes(msg), Message_getLength(msg));
|
||||
|
||||
Err(Message_epush(msg, &ip6, sizeof(struct Headers_IP6Header)));
|
||||
|
||||
Err(TUNMessageType_push(msg, Ethernet_TYPE_IP6));
|
||||
|
||||
Log_debug(ns->log, "Sending neighbor advert");
|
||||
|
||||
return Iface_next(&ns->external, msg);
|
||||
}
|
||||
|
||||
static Iface_DEFUN receiveMessage(Message_t* msg, struct Iface* external)
|
||||
{
|
||||
struct NDPServer_pvt* ns = Identity_containerOf(external, struct NDPServer_pvt, external);
|
||||
|
||||
if (Message_getLength(msg) > Headers_IP6Header_SIZE + 4) {
|
||||
uint16_t ethertype = -1;
|
||||
Err(TUNMessageType_pop(ðertype, msg));
|
||||
if (ethertype != Ethernet_TYPE_IP6) {
|
||||
} else if (isNeighborSolicitation(msg, ns)) {
|
||||
//TODO(cjdns, Kubuxu): Filtering basing on cjdns network and tunnels.
|
||||
return answerNeighborSolicitation(msg, ns);
|
||||
}
|
||||
Err(TUNMessageType_push(msg, ethertype));
|
||||
}
|
||||
return Iface_next(&ns->pub.internal, msg);
|
||||
}
|
||||
|
||||
static Iface_DEFUN sendMessage(Message_t* msg, struct Iface* internal)
|
||||
{
|
||||
struct NDPServer_pvt* ns = Identity_containerOf(internal, struct NDPServer_pvt, pub.internal);
|
||||
return Iface_next(&ns->external, msg);
|
||||
}
|
||||
|
||||
struct NDPServer* NDPServer_new(struct Iface* external,
|
||||
struct Log* log,
|
||||
uint8_t localMac[Ethernet_ADDRLEN],
|
||||
struct Allocator* alloc)
|
||||
{
|
||||
struct NDPServer_pvt* out = Allocator_calloc(alloc, sizeof(struct NDPServer_pvt), 1);
|
||||
Identity_set(out);
|
||||
out->external.send = receiveMessage;
|
||||
Iface_plumb(&out->external, external);
|
||||
out->pub.internal.send = sendMessage;
|
||||
out->log = log;
|
||||
Bits_memcpy(out->localMac, localMac, Ethernet_ADDRLEN);
|
||||
return &out->pub;
|
||||
}
|
@@ -1,35 +0,0 @@
|
||||
/* vim: set expandtab ts=4 sw=4: */
|
||||
/*
|
||||
* You may redistribute this program and/or modify it under the terms of
|
||||
* the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef NDPServer_H
|
||||
#define NDPServer_H
|
||||
|
||||
#include "interface/Iface.h"
|
||||
#include "memory/Allocator.h"
|
||||
#include "util/log/Log.h"
|
||||
#include "wire/Ethernet.h"
|
||||
#include "util/Linker.h"
|
||||
Linker_require("interface/tuntap/NDPServer.c")
|
||||
|
||||
struct NDPServer
|
||||
{
|
||||
struct Iface internal;
|
||||
};
|
||||
|
||||
struct NDPServer* NDPServer_new(struct Iface* external,
|
||||
struct Log* log,
|
||||
uint8_t localMac[Ethernet_ADDRLEN],
|
||||
struct Allocator* alloc);
|
||||
|
||||
#endif
|
@@ -1,109 +0,0 @@
|
||||
/* vim: set expandtab ts=4 sw=4: */
|
||||
/*
|
||||
* You may redistribute this program and/or modify it under the terms of
|
||||
* the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "interface/tuntap/TAPWrapper.h"
|
||||
#include "interface/tuntap/TUNMessageType.h"
|
||||
#include "util/Bits.h"
|
||||
#include "util/Identity.h"
|
||||
#include "util/AddrTools.h"
|
||||
#include "util/Defined.h"
|
||||
#include "wire/Message.h"
|
||||
#include "wire/Ethernet.h"
|
||||
#include "wire/Error.h"
|
||||
|
||||
struct TAPWrapper_pvt
|
||||
{
|
||||
struct TAPWrapper pub;
|
||||
struct Iface external;
|
||||
struct Log* log;
|
||||
Identity
|
||||
};
|
||||
|
||||
static Iface_DEFUN receiveMessage(Message_t* msg, struct Iface* external)
|
||||
{
|
||||
struct TAPWrapper_pvt* tw = Identity_containerOf(external, struct TAPWrapper_pvt, external);
|
||||
|
||||
if (Message_getLength(msg) < Ethernet_SIZE-2) {
|
||||
Log_debug(tw->log, "runt");
|
||||
return Error(msg, "RUNT");
|
||||
}
|
||||
|
||||
// wacky 14 byte headers, back off into outer-space to create the padding...
|
||||
Err(Message_eshift(msg, 2));
|
||||
|
||||
struct Ethernet eth;
|
||||
Err(Message_epop(msg, ð, sizeof(struct Ethernet)));
|
||||
|
||||
// Not for us and not multicast...
|
||||
if (Bits_memcmp(eth.destAddr, TAPWrapper_LOCAL_MAC, Ethernet_ADDRLEN)
|
||||
&& !(eth.destAddr[0] & 0x01))
|
||||
{
|
||||
if (Defined(Log_DEBUG)) {
|
||||
uint8_t printedMac[18];
|
||||
AddrTools_printMac(printedMac, eth.destAddr);
|
||||
Log_debug(tw->log, "Packet destine for unknown ethernet MAC [%s]", printedMac);
|
||||
}
|
||||
//return 0;
|
||||
}
|
||||
|
||||
if (Bits_memcmp(eth.srcAddr, tw->pub.peerAddress, Ethernet_ADDRLEN)) {
|
||||
if (Bits_isZero(tw->pub.peerAddress, Ethernet_ADDRLEN)) {
|
||||
Bits_memcpy(tw->pub.peerAddress, eth.srcAddr, Ethernet_ADDRLEN);
|
||||
} else {
|
||||
#ifdef Log_DEBUG
|
||||
uint8_t printedMac[18];
|
||||
AddrTools_printMac(printedMac, eth.srcAddr);
|
||||
Log_debug(tw->log, "DROP Packet with unexpected source MAC [%s]", printedMac);
|
||||
#endif
|
||||
return Error(msg, "INVALID");
|
||||
}
|
||||
}
|
||||
Err(TUNMessageType_push(msg, eth.ethertype));
|
||||
return Iface_next(&tw->pub.internal, msg);
|
||||
}
|
||||
|
||||
static Iface_DEFUN sendMessage(Message_t* msg, struct Iface* internal)
|
||||
{
|
||||
struct TAPWrapper_pvt* tw = Identity_containerOf(internal, struct TAPWrapper_pvt, pub.internal);
|
||||
|
||||
uint16_t etherType = -1;
|
||||
Err(TUNMessageType_pop(ðerType, msg));
|
||||
struct Ethernet eth = { .ethertype = etherType };
|
||||
Bits_memcpy(eth.srcAddr, TAPWrapper_LOCAL_MAC, Ethernet_ADDRLEN);
|
||||
Bits_memcpy(eth.destAddr, tw->pub.peerAddress, Ethernet_ADDRLEN);
|
||||
if (Bits_isZero(tw->pub.peerAddress, Ethernet_ADDRLEN)) {
|
||||
Log_debug(tw->log, "DROP Packet because peers MAC is not yet known");
|
||||
return Error(msg, "INVALID");
|
||||
}
|
||||
|
||||
Err(Message_epush(msg, ð, sizeof(struct Ethernet)));
|
||||
|
||||
// struct Ethernet contains 2 bytes of padding at the beginning.
|
||||
Err(Message_eshift(msg, -2));
|
||||
|
||||
return Iface_next(&tw->external, msg);
|
||||
}
|
||||
|
||||
struct TAPWrapper* TAPWrapper_new(struct Iface* external,
|
||||
struct Log* log,
|
||||
struct Allocator* alloc)
|
||||
{
|
||||
struct TAPWrapper_pvt* out = Allocator_calloc(alloc, sizeof(struct TAPWrapper_pvt), 1);
|
||||
Identity_set(out);
|
||||
out->log = log;
|
||||
out->external.send = receiveMessage;
|
||||
out->pub.internal.send = sendMessage;
|
||||
Iface_plumb(external, &out->external);
|
||||
return &out->pub;
|
||||
}
|
@@ -1,43 +0,0 @@
|
||||
/* vim: set expandtab ts=4 sw=4: */
|
||||
/*
|
||||
* You may redistribute this program and/or modify it under the terms of
|
||||
* the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef TAPWrapper_H
|
||||
#define TAPWrapper_H
|
||||
|
||||
#include "interface/Iface.h"
|
||||
#include "memory/Allocator.h"
|
||||
#include "util/log/Log.h"
|
||||
#include "wire/Ethernet.h"
|
||||
#include "util/Linker.h"
|
||||
Linker_require("interface/tuntap/TAPWrapper.c")
|
||||
|
||||
struct TAPWrapper
|
||||
{
|
||||
struct Iface internal;
|
||||
|
||||
/** This is the peer's MAC address (zero before initialization). */
|
||||
uint8_t peerAddress[Ethernet_ADDRLEN];
|
||||
};
|
||||
|
||||
/**
|
||||
* This is the address which we will report to the peer as our address.
|
||||
* As per IEEE-802 it is non-multicast and non-locally-assigned, and it begins with fc :)
|
||||
*/
|
||||
#define TAPWrapper_LOCAL_MAC "\xfc\x00\x00\x00\x00\x00"
|
||||
|
||||
struct TAPWrapper* TAPWrapper_new(struct Iface* external,
|
||||
struct Log* log,
|
||||
struct Allocator* alloc);
|
||||
|
||||
#endif
|
69
interface/tuntap/TUNInterface.c
Normal file
69
interface/tuntap/TUNInterface.c
Normal file
@@ -0,0 +1,69 @@
|
||||
/* vim: set expandtab ts=4 sw=4: */
|
||||
/*
|
||||
* You may redistribute this program and/or modify it under the terms of
|
||||
* the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "interface/tuntap/TUNInterface_pvt.h"
|
||||
#include "rust/cjdns_sys/RTypes.h"
|
||||
#include "rust/cjdns_sys/Rffi.h"
|
||||
|
||||
typedef struct TUNInterface_pvt {
|
||||
TUNInterface_t pub;
|
||||
Rffi_SocketIface_t* si;
|
||||
Identity
|
||||
} TUNInterface_pvt_t;
|
||||
|
||||
Err_DEFUN TUNInterface_forFd(
|
||||
TUNInterface_t** out,
|
||||
int fd,
|
||||
struct Allocator* alloc)
|
||||
{
|
||||
TUNInterface_pvt_t* pvt = Allocator_calloc(alloc, sizeof(TUNInterface_pvt_t), 1);
|
||||
Identity_set(pvt);
|
||||
Err(Rffi_socketForFd(
|
||||
&pvt->pub.iface,
|
||||
&pvt->si,
|
||||
fd,
|
||||
RTypes_SocketType_Frames,
|
||||
alloc));
|
||||
*out = &pvt->pub;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Err_DEFUN TUNInterface_new(
|
||||
TUNInterface_t** out,
|
||||
const char* interfaceName,
|
||||
char assignedInterfaceName[TUNInterface_IFNAMSIZ],
|
||||
struct Log* logger,
|
||||
struct Allocator* alloc)
|
||||
{
|
||||
TUNInterface_pvt_t* pvt = Allocator_calloc(alloc, sizeof(TUNInterface_pvt_t), 1);
|
||||
Identity_set(pvt);
|
||||
Err(TUNInterface_newImpl(
|
||||
&pvt->si,
|
||||
&pvt->pub.iface,
|
||||
interfaceName,
|
||||
assignedInterfaceName,
|
||||
logger,
|
||||
alloc));
|
||||
*out = &pvt->pub;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Err_DEFUN TUNInterface_workerStates(
|
||||
Object_t** out,
|
||||
TUNInterface_t* tt,
|
||||
Allocator_t* alloc)
|
||||
{
|
||||
TUNInterface_pvt_t* pvt = Identity_check((TUNInterface_pvt_t*)tt);
|
||||
return Rffi_socketWorkerStates(out, pvt->si, alloc);
|
||||
}
|
@@ -16,12 +16,10 @@
|
||||
#define TUNInterface_H
|
||||
|
||||
#include "exception/Err.h"
|
||||
#include "interface/Iface.h"
|
||||
#include "memory/Allocator.h"
|
||||
#include "util/events/EventBase.h"
|
||||
#include "util/log/Log.h"
|
||||
#include "util/Linker.h"
|
||||
Linker_require("interface/tuntap/TUNInterface_" + builder.config.systemName + ".c")
|
||||
Linker_require("interface/tuntap/TUNInterface.c")
|
||||
|
||||
/**
|
||||
* This is the maximum size that will be accepted as an interface name.
|
||||
@@ -34,23 +32,35 @@ Linker_require("interface/tuntap/TUNInterface_" + builder.config.systemName + ".
|
||||
#define TUNInterface_IFNAMSIZ 16
|
||||
#endif
|
||||
|
||||
typedef struct TUNInterface {
|
||||
Iface_t* iface;
|
||||
} TUNInterface_t;
|
||||
|
||||
/**
|
||||
* Create a new TUNInterface.
|
||||
*
|
||||
* @param interfaceName the interface name you *want* to use or NULL to let the kernel decide.
|
||||
* @param assignedInterfaceName an empty buffer which will be filled in with the interface
|
||||
* name that is assigned.
|
||||
* @param isTapMode if true, the TUN device will be initialized in TAP mode if supported.
|
||||
* @param base the libevent event base to use for listening for incoming packet events.
|
||||
* @param logger for logging messages about the tun device.
|
||||
* @param allocator a means of getting memory.
|
||||
* @return a Interface.
|
||||
*/
|
||||
Err_DEFUN TUNInterface_new(struct Iface** out,
|
||||
const char* interfaceName,
|
||||
char assignedInterfaceName[TUNInterface_IFNAMSIZ],
|
||||
int isTapMode,
|
||||
EventBase_t* base,
|
||||
struct Log* logger,
|
||||
struct Allocator* alloc);
|
||||
Err_DEFUN TUNInterface_new(
|
||||
TUNInterface_t** out,
|
||||
const char* interfaceName,
|
||||
char assignedInterfaceName[TUNInterface_IFNAMSIZ],
|
||||
struct Log* logger,
|
||||
struct Allocator* alloc);
|
||||
|
||||
Err_DEFUN TUNInterface_workerStates(
|
||||
Object_t** out,
|
||||
TUNInterface_t* tt,
|
||||
Allocator_t* alloc);
|
||||
|
||||
Err_DEFUN TUNInterface_forFd(
|
||||
TUNInterface_t** out,
|
||||
int fd,
|
||||
struct Allocator* alloc);
|
||||
|
||||
#endif
|
||||
|
@@ -12,10 +12,10 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "interface/tuntap/TUNInterface.h"
|
||||
#include "interface/tuntap/TUNInterface_pvt.h"
|
||||
#include "exception/Err.h"
|
||||
#include "interface/tuntap/BSDMessageTypeWrapper.h"
|
||||
#include "util/AddrTools.h"
|
||||
#include "rust/cjdns_sys/RTypes.h"
|
||||
#include "util/events/Socket.h"
|
||||
#include "util/CString.h"
|
||||
|
||||
@@ -41,16 +41,14 @@
|
||||
#define APPLE_UTUN_CONTROL "com.apple.net.utun_control"
|
||||
#define UTUN_OPT_IFNAME 2
|
||||
|
||||
Err_DEFUN TUNInterface_new(struct Iface** out,
|
||||
const char* interfaceName,
|
||||
char assignedInterfaceName[TUNInterface_IFNAMSIZ],
|
||||
int isTapMode,
|
||||
EventBase_t* base,
|
||||
struct Log* logger,
|
||||
struct Allocator* alloc)
|
||||
Err_DEFUN TUNInterface_newImpl(
|
||||
Rffi_SocketIface_t** sout,
|
||||
struct Iface** out,
|
||||
const char* interfaceName,
|
||||
char assignedInterfaceName[TUNInterface_IFNAMSIZ],
|
||||
struct Log* logger,
|
||||
struct Allocator* alloc)
|
||||
{
|
||||
if (isTapMode) { Err_raise(alloc, "tap mode not supported on this platform"); }
|
||||
|
||||
int maxNameSize = (IFNAMSIZ < TUNInterface_IFNAMSIZ) ? IFNAMSIZ : TUNInterface_IFNAMSIZ;
|
||||
int tunUnit = 0; /* allocate dynamically by default */
|
||||
|
||||
@@ -113,7 +111,7 @@ Err_DEFUN TUNInterface_new(struct Iface** out,
|
||||
}
|
||||
|
||||
struct Iface* iface = NULL;
|
||||
Err(Socket_forFd(&iface, tunFd, Socket_forFd_FRAMES, alloc));
|
||||
Err(Rffi_socketForFd(&iface, sout, tunFd, RTypes_SocketType_Frames, alloc));
|
||||
|
||||
struct BSDMessageTypeWrapper* bmtw = BSDMessageTypeWrapper_new(alloc, logger);
|
||||
Iface_plumb(iface, &bmtw->wireSide);
|
||||
|
@@ -12,10 +12,9 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "interface/tuntap/TUNInterface.h"
|
||||
#include "interface/tuntap/TUNInterface_pvt.h"
|
||||
#include "exception/Err.h"
|
||||
#include "interface/tuntap/BSDMessageTypeWrapper.h"
|
||||
#include "util/AddrTools.h"
|
||||
#include "util/events/Socket.h"
|
||||
|
||||
#include <errno.h>
|
||||
@@ -38,18 +37,16 @@
|
||||
#include <netinet6/in6_var.h>
|
||||
#include <netinet6/nd6.h>
|
||||
|
||||
Err_DEFUN TUNInterface_new(struct Iface** out,
|
||||
const char* interfaceName,
|
||||
char assignedInterfaceName[TUNInterface_IFNAMSIZ],
|
||||
int isTapMode,
|
||||
EventBase_t* base,
|
||||
struct Log* logger,
|
||||
struct Allocator* alloc)
|
||||
Err_DEFUN TUNInterface_newImpl(
|
||||
Rffi_SocketIface_t** sout,
|
||||
struct Iface** out,
|
||||
const char* interfaceName,
|
||||
char assignedInterfaceName[TUNInterface_IFNAMSIZ],
|
||||
struct Log* logger,
|
||||
struct Allocator* alloc)
|
||||
{
|
||||
char deviceFile[TUNInterface_IFNAMSIZ];
|
||||
|
||||
if (isTapMode) { Err_raise(alloc, "tap mode not supported on this platform"); }
|
||||
|
||||
// We are on FreeBSD so we just need to read /dev/tunxx to create the tun interface
|
||||
if (interfaceName) {
|
||||
snprintf(deviceFile,TUNInterface_IFNAMSIZ,"/dev/%s",interfaceName);
|
||||
@@ -114,7 +111,7 @@ Err_DEFUN TUNInterface_new(struct Iface** out,
|
||||
}
|
||||
|
||||
struct Iface* s = NULL;
|
||||
Err(Socket_forFd(&s, tunFd, Socket_forFd_FRAMES, alloc));
|
||||
Err(Rffi_socketForFd(&s, sout, tunFd, RTypes_SocketType_Frames, alloc));
|
||||
|
||||
struct BSDMessageTypeWrapper* bmtw = BSDMessageTypeWrapper_new(alloc, logger);
|
||||
Iface_plumb(s, &bmtw->wireSide);
|
||||
|
@@ -12,7 +12,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "interface/tuntap/TUNInterface.h"
|
||||
#include "interface/tuntap/TUNInterface_pvt.h"
|
||||
#include "exception/Err.h"
|
||||
#include "memory/Allocator.h"
|
||||
#include "util/events/EventBase.h"
|
||||
@@ -41,13 +41,13 @@
|
||||
#define DEVICE_PATH "/dev/net/tun"
|
||||
#endif
|
||||
|
||||
Err_DEFUN TUNInterface_new(struct Iface** out,
|
||||
const char* interfaceName,
|
||||
char assignedInterfaceName[TUNInterface_IFNAMSIZ],
|
||||
int isTapMode,
|
||||
EventBase_t* base,
|
||||
struct Log* logger,
|
||||
struct Allocator* alloc)
|
||||
Err_DEFUN TUNInterface_newImpl(
|
||||
Rffi_SocketIface_t** sout,
|
||||
struct Iface** out,
|
||||
const char* interfaceName,
|
||||
char assignedInterfaceName[TUNInterface_IFNAMSIZ],
|
||||
struct Log* logger,
|
||||
struct Allocator* alloc)
|
||||
{
|
||||
uint32_t maxNameSize = (IFNAMSIZ < TUNInterface_IFNAMSIZ) ? IFNAMSIZ : TUNInterface_IFNAMSIZ;
|
||||
Log_info(logger, "Initializing tun device [%s]", ((interfaceName) ? interfaceName : "auto"));
|
||||
@@ -74,5 +74,5 @@ Err_DEFUN TUNInterface_new(struct Iface** out,
|
||||
CString_safeStrncpy(assignedInterfaceName, ifRequest.ifr_name, maxNameSize);
|
||||
}
|
||||
|
||||
return Socket_forFd(out, tunFd, Socket_forFd_FRAMES, alloc);
|
||||
return Rffi_socketForFd(out, sout, tunFd, RTypes_SocketType_Frames, alloc);
|
||||
}
|
||||
|
@@ -12,7 +12,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "interface/tuntap/TUNInterface.h"
|
||||
#include "interface/tuntap/TUNInterface_pvt.h"
|
||||
#include "exception/Err.h"
|
||||
#include "interface/tuntap/BSDMessageTypeWrapper.h"
|
||||
#include "util/events/Socket.h"
|
||||
@@ -38,15 +38,14 @@
|
||||
|
||||
/* Tun Configurator for NetBSD. */
|
||||
|
||||
Err_DEFUN TUNInterface_new(struct Iface** out,
|
||||
const char* interfaceName,
|
||||
char assignedInterfaceName[TUNInterface_IFNAMSIZ],
|
||||
int isTapMode,
|
||||
EventBase_t* base,
|
||||
struct Log* logger,
|
||||
struct Allocator* alloc)
|
||||
Err_DEFUN TUNInterface_newImpl(
|
||||
Rffi_SocketIface_t** sout,
|
||||
struct Iface** out,
|
||||
const char* interfaceName,
|
||||
char assignedInterfaceName[TUNInterface_IFNAMSIZ],
|
||||
struct Log* logger,
|
||||
struct Allocator* alloc)
|
||||
{
|
||||
if (isTapMode) { Err_raise(alloc, "tap mode not supported on this platform"); }
|
||||
int err;
|
||||
char file[TUNInterface_IFNAMSIZ];
|
||||
int i;
|
||||
@@ -88,7 +87,7 @@ Err_DEFUN TUNInterface_new(struct Iface** out,
|
||||
}
|
||||
}
|
||||
struct Iface* s = NULL;
|
||||
Err(Socket_forFd(&s, tunFd, Socket_forFd_FRAMES, alloc));
|
||||
Err(Rffi_socketForFd(&s, sout, tunFd, RTypes_SocketType_Frames, alloc));
|
||||
|
||||
struct BSDMessageTypeWrapper* bmtw = BSDMessageTypeWrapper_new(alloc, logger);
|
||||
Iface_plumb(s, &bmtw->wireSide);
|
||||
|
@@ -38,15 +38,14 @@
|
||||
|
||||
/* Tun Configurator for OpenBSD. */
|
||||
|
||||
Err_DEFUN TUNInterface_new(struct Iface** out,
|
||||
const char* interfaceName,
|
||||
char assignedInterfaceName[TUNInterface_IFNAMSIZ],
|
||||
int isTapMode,
|
||||
EventBase_t* base,
|
||||
struct Log* logger,
|
||||
struct Allocator* alloc)
|
||||
Err_DEFUN TUNInterface_newImpl(
|
||||
Rffi_SocketIface_t** sout,
|
||||
struct Iface** out,
|
||||
const char* interfaceName,
|
||||
char assignedInterfaceName[TUNInterface_IFNAMSIZ],
|
||||
struct Log* logger,
|
||||
struct Allocator* alloc)
|
||||
{
|
||||
if (isTapMode) { Err_raise(alloc, "tap mode not supported on this platform"); }
|
||||
int err;
|
||||
char file[TUNInterface_IFNAMSIZ];
|
||||
int ppa = -1; // to store the tunnel device index
|
||||
@@ -76,7 +75,7 @@ Err_DEFUN TUNInterface_new(struct Iface** out,
|
||||
}
|
||||
}
|
||||
struct Iface* s = NULL;
|
||||
Err(Socket_forFd(&s, tunFd, Socket_forFd_FRAMES, alloc));
|
||||
Err(Rffi_socketForFd(&s, sout, tunFd, RTypes_SocketType_Frames, alloc));
|
||||
|
||||
struct BSDMessageTypeWrapper* bmtw = BSDMessageTypeWrapper_new(alloc, logger);
|
||||
Iface_plumb(s, &bmtw->wireSide);
|
||||
|
@@ -12,24 +12,20 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef ARPServer_H
|
||||
#define ARPServer_H
|
||||
#ifndef TUNInterface_pvt_H
|
||||
#define TUNInterface_pvt_H
|
||||
|
||||
#include "interface/Iface.h"
|
||||
#include "memory/Allocator.h"
|
||||
#include "util/log/Log.h"
|
||||
#include "wire/Ethernet.h"
|
||||
#include "interface/tuntap/TUNInterface.h"
|
||||
#include "rust/cjdns_sys/Rffi.h"
|
||||
#include "util/Linker.h"
|
||||
Linker_require("interface/tuntap/ARPServer.c")
|
||||
Linker_require("interface/tuntap/TUNInterface_" + builder.config.systemName + ".c")
|
||||
|
||||
struct ARPServer
|
||||
{
|
||||
struct Iface internal;
|
||||
};
|
||||
Err_DEFUN TUNInterface_newImpl(
|
||||
Rffi_SocketIface_t** sout,
|
||||
struct Iface** out,
|
||||
const char* interfaceName,
|
||||
char assignedInterfaceName[TUNInterface_IFNAMSIZ],
|
||||
struct Log* logger,
|
||||
struct Allocator* alloc);
|
||||
|
||||
struct ARPServer* ARPServer_new(struct Iface* external,
|
||||
struct Log* log,
|
||||
uint8_t localMac[Ethernet_ADDRLEN],
|
||||
struct Allocator* alloc);
|
||||
|
||||
#endif
|
||||
#endif
|
@@ -13,6 +13,8 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "interface/tuntap/TUNInterface.h"
|
||||
#include "rust/cjdns_sys/RTypes.h"
|
||||
#include "rust/cjdns_sys/Rffi.h"
|
||||
#include "util/AddrTools.h"
|
||||
#include "util/Identity.h"
|
||||
#include "util/events/Socket.h"
|
||||
@@ -88,17 +90,14 @@ static Iface_DEFUN incomingFromUs(Message_t* message, struct Iface* internalIf)
|
||||
return Iface_next(&ctx->externalIf, message);
|
||||
}
|
||||
|
||||
Err_DEFUN TUNInterface_new(struct Iface** out,
|
||||
const char* interfaceName,
|
||||
char assignedInterfaceName[TUNInterface_IFNAMSIZ],
|
||||
int isTapMode,
|
||||
EventBase_t* base,
|
||||
struct Log* logger,
|
||||
struct Allocator* alloc)
|
||||
Err_DEFUN TUNInterface_newImpl(
|
||||
Rffi_SocketIface_t** sout,
|
||||
struct Iface** out,
|
||||
const char* interfaceName,
|
||||
char assignedInterfaceName[TUNInterface_IFNAMSIZ],
|
||||
struct Log* logger,
|
||||
struct Allocator* alloc)
|
||||
{
|
||||
// tap mode is not supported at all by the sunos tun driver.
|
||||
if (isTapMode) { Err_raise(alloc, "tap mode not supported on this platform"); }
|
||||
|
||||
// Extract the number eg: 0 from tun0
|
||||
int ppa = 0;
|
||||
if (interfaceName) {
|
||||
@@ -184,7 +183,7 @@ Err_DEFUN TUNInterface_new(struct Iface** out,
|
||||
close(ipFd);
|
||||
|
||||
struct Iface* s = NULL;
|
||||
Err(Socket_forFd(&s, tunFd, Socket_forFd_FRAMES, alloc));
|
||||
Err(Rffi_socketForFd(&s, sout, tunFd, RTypes_SocketType_Frames, alloc));
|
||||
|
||||
struct TUNInterface_Illumos_pvt* ctx =
|
||||
Allocator_clone(alloc, (&(struct TUNInterface_Illumos_pvt) {
|
||||
|
@@ -1,51 +0,0 @@
|
||||
/* vim: set expandtab ts=4 sw=4: */
|
||||
/*
|
||||
* You may redistribute this program and/or modify it under the terms of
|
||||
* the GNU General Public License as published by the Free Software Foundation,
|
||||
* either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "interface/tuntap/TUNInterface.h"
|
||||
#include "memory/Allocator.h"
|
||||
#include "util/log/Log.h"
|
||||
#include "util/log/FileWriterLog.h"
|
||||
#include "util/platform/netdev/NetDev.h"
|
||||
#include "test/RootTest.h"
|
||||
#include "interface/tuntap/test/TUNTools.h"
|
||||
#include "interface/tuntap/TAPWrapper.h"
|
||||
#include "interface/tuntap/NDPServer.h"
|
||||
#include "interface/tuntap/ARPServer.h"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
struct Allocator* alloc = Allocator_new(1<<20);
|
||||
EventBase_t* base = EventBase_new(alloc);
|
||||
struct Log* log = FileWriterLog_new(stdout, alloc);
|
||||
|
||||
struct Sockaddr* addrA = Sockaddr_fromBytes(TUNTools_testIP6AddrA, Sockaddr_AF_INET6, alloc);
|
||||
struct Sockaddr* addrB = Sockaddr_fromBytes(TUNTools_testIP6AddrB, Sockaddr_AF_INET6, alloc);
|
||||
|
||||
char assignedIfName[TUNInterface_IFNAMSIZ];
|
||||
struct Iface* tap = NULL;
|
||||
Err_assert(TUNInterface_new(&tap, NULL, assignedIfName, 1, base, log, alloc));
|
||||
struct TAPWrapper* tapWrapper = TAPWrapper_new(tap, log, alloc);
|
||||
|
||||
// Now setup the NDP server so the tun will work correctly.
|
||||
struct NDPServer* ndp = NDPServer_new(&tapWrapper->internal, log, TAPWrapper_LOCAL_MAC, alloc);
|
||||
struct ARPServer* arp = ARPServer_new(&ndp->internal, log, TAPWrapper_LOCAL_MAC, alloc);
|
||||
|
||||
addrA->flags |= Sockaddr_flags_PREFIX;
|
||||
addrA->prefix = 126;
|
||||
Err_assert(NetDev_addAddress(assignedIfName, addrA, log, alloc));
|
||||
|
||||
TUNTools_echoTest(addrA, addrB, TUNTools_genericIP6Echo, &arp->internal, base, log, alloc);
|
||||
Allocator_free(alloc);
|
||||
return 0;
|
||||
}
|
@@ -70,13 +70,13 @@ int main(int argc, char** argv)
|
||||
struct Sockaddr* addrB = Sockaddr_fromBytes(testAddrB, Sockaddr_AF_INET, alloc);
|
||||
|
||||
char assignedIfName[TUNInterface_IFNAMSIZ];
|
||||
struct Iface* tun = NULL;
|
||||
Err_assert(TUNInterface_new(&tun, NULL, assignedIfName, 0, base, logger, alloc));
|
||||
TUNInterface_t* tt = NULL;
|
||||
Err_assert(TUNInterface_new(&tt, NULL, assignedIfName, logger, alloc));
|
||||
addrA->flags |= Sockaddr_flags_PREFIX;
|
||||
addrA->prefix = 30;
|
||||
Err_assert(NetDev_addAddress(assignedIfName, addrA, logger, alloc));
|
||||
|
||||
TUNTools_echoTest(addrA, addrB, receiveMessageTUN, tun, base, logger, alloc);
|
||||
TUNTools_echoTest(addrA, addrB, receiveMessageTUN, tt->iface, base, logger, alloc);
|
||||
Allocator_free(alloc);
|
||||
return 0;
|
||||
}
|
||||
|
@@ -35,13 +35,13 @@ int main(int argc, char** argv)
|
||||
struct Sockaddr* addrB = Sockaddr_fromBytes(TUNTools_testIP6AddrB, Sockaddr_AF_INET6, alloc);
|
||||
|
||||
char assignedIfName[TUNInterface_IFNAMSIZ];
|
||||
struct Iface* tun = NULL;
|
||||
Err_assert(TUNInterface_new(&tun, NULL, assignedIfName, 0, base, logger, alloc));
|
||||
TUNInterface_t* tt = NULL;
|
||||
Err_assert(TUNInterface_new(&tt, NULL, assignedIfName, logger, alloc));
|
||||
addrA->flags |= Sockaddr_flags_PREFIX;
|
||||
addrA->prefix = 126;
|
||||
Err_assert(NetDev_addAddress(assignedIfName, addrA, logger, alloc));
|
||||
|
||||
TUNTools_echoTest(addrA, addrB, TUNTools_genericIP6Echo, tun, base, logger, alloc);
|
||||
TUNTools_echoTest(addrA, addrB, TUNTools_genericIP6Echo, tt->iface, base, logger, alloc);
|
||||
Allocator_free(alloc);
|
||||
return 0;
|
||||
}
|
||||
|
@@ -35,8 +35,8 @@ int main(int argc, char** argv)
|
||||
struct Sockaddr* addrC = Sockaddr_fromBytes(TUNTools_testIP6AddrC, Sockaddr_AF_INET6, alloc);
|
||||
|
||||
char assignedIfName[TUNInterface_IFNAMSIZ];
|
||||
struct Iface* tun = NULL;
|
||||
Err_assert(TUNInterface_new(&tun, NULL, assignedIfName, 0, base, logger, alloc));
|
||||
TUNInterface_t* tt = NULL;
|
||||
Err_assert(TUNInterface_new(&tt, NULL, assignedIfName, logger, alloc));
|
||||
addrA->flags |= Sockaddr_flags_PREFIX;
|
||||
addrA->prefix = 126;
|
||||
Err_assert(NetDev_addAddress(assignedIfName, addrA, logger, alloc));
|
||||
@@ -44,7 +44,7 @@ int main(int argc, char** argv)
|
||||
addrC->prefix = 125;
|
||||
Err_assert(NetDev_setRoutes(assignedIfName, ((struct Sockaddr*[]) { addrC }), 1, logger, alloc));
|
||||
|
||||
TUNTools_echoTest(addrA, addrC, TUNTools_genericIP6Echo, tun, base, logger, alloc);
|
||||
TUNTools_echoTest(addrA, addrC, TUNTools_genericIP6Echo, tt->iface, base, logger, alloc);
|
||||
Allocator_free(alloc);
|
||||
return 0;
|
||||
}
|
||||
|
@@ -39,7 +39,7 @@ static AddrIface_t* setupUDP(EventBase_t* base,
|
||||
struct UDPAddrIface* udp = NULL;
|
||||
RTypes_Error_t* er = NULL;
|
||||
for (int i = 0; i < 20; i++) {
|
||||
er = UDPAddrIface_new(&udp, base, bindAddr, allocator, logger);
|
||||
er = UDPAddrIface_new(&udp, bindAddr, allocator);
|
||||
if (udp) {
|
||||
break;
|
||||
}
|
||||
|
@@ -11,7 +11,6 @@ cjdns-crypto = { workspace = true }
|
||||
cjdns-keys = { workspace = true }
|
||||
cjdns-bytes = { workspace = true }
|
||||
cjdns-bencode = { workspace = true }
|
||||
bendy = { workspace = true }
|
||||
sodiumoxide = { workspace = true }
|
||||
hex = { workspace = true }
|
||||
log = { workspace = true }
|
||||
@@ -32,6 +31,7 @@ env_logger = { workspace = true }
|
||||
byteorder = { workspace = true }
|
||||
trust-dns-resolver = { workspace = true }
|
||||
ipnetwork = { workspace = true }
|
||||
num_enum = { workspace = true }
|
||||
|
||||
[build_dependencies]
|
||||
cc = { workspace = true }
|
||||
|
@@ -40,6 +40,13 @@ typedef enum {
|
||||
RTypes_CryptoAuth_State_t_Established = 100,
|
||||
} RTypes_CryptoAuth_State_t;
|
||||
|
||||
enum RTypes_SocketType {
|
||||
RTypes_SocketType_SendToFrames,
|
||||
RTypes_SocketType_Frames,
|
||||
RTypes_SocketType_Stream,
|
||||
};
|
||||
typedef int32_t RTypes_SocketType;
|
||||
|
||||
typedef struct RTypes_Error_t RTypes_Error_t;
|
||||
|
||||
typedef struct RTypes_EventLoop_t RTypes_EventLoop_t;
|
||||
@@ -109,6 +116,7 @@ typedef struct {
|
||||
RTypes_CryptoAuth2_TryHandshake_Ret_t g;
|
||||
RTypes_Seeder_DnsSeeds_t h;
|
||||
RTypes_EventLoop_t *i;
|
||||
RTypes_SocketType j;
|
||||
} RTypes_ExportMe;
|
||||
|
||||
#endif /* RTypes_H */
|
||||
|
@@ -11,6 +11,8 @@ typedef struct Rffi_FdReadableTx Rffi_FdReadableTx;
|
||||
|
||||
typedef struct Rffi_Seeder Rffi_Seeder;
|
||||
|
||||
typedef struct Rffi_SocketIface_t Rffi_SocketIface_t;
|
||||
|
||||
typedef struct Rffi_SocketServer Rffi_SocketServer;
|
||||
|
||||
/**
|
||||
@@ -170,6 +172,10 @@ int32_t Rffi_udpIfaceGetFd(Rffi_UDPIface_pvt *iface);
|
||||
|
||||
int32_t Rffi_udpIfaceSetBroadcast(Rffi_UDPIface_pvt *iface, bool broadcast);
|
||||
|
||||
RTypes_Error_t *Rffi_udpIface_worker_states(Object_t **outP,
|
||||
Rffi_UDPIface_pvt *iface,
|
||||
Allocator_t *alloc);
|
||||
|
||||
int32_t Rffi_udpIfaceSetDscp(Rffi_UDPIface_pvt *iface, uint8_t dscp);
|
||||
|
||||
RTypes_Error_t *Rffi_udpIfaceNew(Rffi_UDPIface **outp,
|
||||
@@ -178,7 +184,15 @@ RTypes_Error_t *Rffi_udpIfaceNew(Rffi_UDPIface **outp,
|
||||
|
||||
RTypes_Error_t *Rffi_fileExists(bool *existsOut, const char *path, Allocator_t *errorAlloc);
|
||||
|
||||
RTypes_Error_t *Rffi_socketForFd(Iface_t **ifOut, int fd, int socket_type, Allocator_t *alloc);
|
||||
RTypes_Error_t *Rffi_socketWorkerStates(Object_t **outP,
|
||||
const Rffi_SocketIface_t *si,
|
||||
Allocator_t *alloc);
|
||||
|
||||
RTypes_Error_t *Rffi_socketForFd(Iface_t **ifOut,
|
||||
Rffi_SocketIface_t **so_out,
|
||||
int fd,
|
||||
RTypes_SocketType st,
|
||||
Allocator_t *alloc);
|
||||
|
||||
RTypes_Error_t *Rffi_unixSocketConnect(Iface_t **ifOut, const char *path, Allocator_t *alloc);
|
||||
|
||||
|
@@ -1,10 +1,13 @@
|
||||
use std::collections::VecDeque;
|
||||
use std::os::fd::AsRawFd;
|
||||
use std::sync::atomic::AtomicI32;
|
||||
use std::time::Duration;
|
||||
use libc::cmsghdr;
|
||||
use num_enum::{IntoPrimitive, TryFromPrimitive};
|
||||
use tokio::io::unix::AsyncFd;
|
||||
use tokio::sync::mpsc::{Receiver, Sender};
|
||||
use tokio::sync::Mutex;
|
||||
use crate::rtypes::RTypes_SocketType;
|
||||
use crate::util::sockaddr::Sockaddr;
|
||||
use std::convert::TryFrom;
|
||||
use std::sync::Arc;
|
||||
@@ -62,12 +65,7 @@ struct Additional {
|
||||
address: [u8; 128],
|
||||
}
|
||||
|
||||
#[derive(PartialEq,Clone,Copy)]
|
||||
pub enum SocketType {
|
||||
SendToFrames,
|
||||
Frames,
|
||||
Stream,
|
||||
}
|
||||
pub type SocketType = RTypes_SocketType;
|
||||
|
||||
struct IoContext<const COUNT: usize> {
|
||||
hdrs: [Mmsghdr; COUNT],
|
||||
@@ -334,6 +332,32 @@ impl <const COUNT: usize> IoContext<COUNT> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug,IntoPrimitive,TryFromPrimitive)]
|
||||
#[repr(i32)]
|
||||
pub enum SendWorkerState {
|
||||
Invalid = -1,
|
||||
Initializing = 0,
|
||||
WaitLock = 1,
|
||||
RecvBatch = 2,
|
||||
WaitFdWritable = 3,
|
||||
WaitFdError = 4,
|
||||
SendBatch = 5,
|
||||
SentBatch = 6,
|
||||
}
|
||||
|
||||
#[derive(Debug,IntoPrimitive,TryFromPrimitive)]
|
||||
#[repr(i32)]
|
||||
pub enum RecvWorkerState {
|
||||
Invalid = -1,
|
||||
Initializing = 0,
|
||||
WaitFdReadable = 1,
|
||||
WaitFdError = 2,
|
||||
RecvBatch = 3,
|
||||
RecievedBatch = 4,
|
||||
IfaceSend = 5,
|
||||
Yield = 6,
|
||||
}
|
||||
|
||||
struct SocketIfaceInternal<T: AsRawFd + Sync + Send> {
|
||||
iface: IfacePvt,
|
||||
st: SocketType,
|
||||
@@ -342,6 +366,9 @@ struct SocketIfaceInternal<T: AsRawFd + Sync + Send> {
|
||||
to_go_out_recv: Mutex<Receiver<Message>>,
|
||||
to_go_out_send: Sender<Message>,
|
||||
done_r: tokio::sync::broadcast::Receiver<()>,
|
||||
|
||||
send_worker_states: Vec<AtomicI32>,
|
||||
recv_worker_states: Vec<AtomicI32>,
|
||||
}
|
||||
impl<T: AsRawFd + Sync + Send> IfRecv for Arc<SocketIfaceInternal<T>> {
|
||||
fn recv(&self, m: Message) -> Result<()> {
|
||||
@@ -369,6 +396,9 @@ impl<T: AsRawFd + Sync + Send + 'static> SocketIfaceInternal<T> {
|
||||
}
|
||||
}
|
||||
}
|
||||
fn send_worker_set_state(self: &Arc<Self>, n: usize, state: SendWorkerState) {
|
||||
self.send_worker_states[n].store(state as i32, std::sync::atomic::Ordering::Relaxed);
|
||||
}
|
||||
async fn send_worker(self: Arc<Self>, n: usize) {
|
||||
let fd_num = n % self.afds.len();
|
||||
let mut ctx: IoContext<SEND_BATCH> = IoContext::new(self.afds[fd_num].as_raw_fd(), self.st);
|
||||
@@ -376,21 +406,27 @@ impl<T: AsRawFd + Sync + Send + 'static> SocketIfaceInternal<T> {
|
||||
let mut batch_vec = Vec::with_capacity(SEND_BATCH);
|
||||
|
||||
loop {
|
||||
self.send_worker_set_state(n, SendWorkerState::WaitLock);
|
||||
let mut tgo = self.to_go_out_recv.lock().await;
|
||||
self.send_worker_set_state(n, SendWorkerState::RecvBatch);
|
||||
tgo.recv_many(&mut batch_vec, RECV_BATCH - batch.len()).await;
|
||||
drop(tgo);
|
||||
batch.extend(batch_vec.drain(..));
|
||||
|
||||
self.send_worker_set_state(n, SendWorkerState::WaitFdWritable);
|
||||
let mut writable = match self.afds[fd_num].writable().await {
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
self.send_worker_set_state(n, SendWorkerState::WaitFdError);
|
||||
log::info!("Error polling fd.writable(): {e} - sleep 1 second");
|
||||
tokio::time::sleep(Duration::from_secs(1)).await;
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
self.send_worker_set_state(n, SendWorkerState::SendBatch);
|
||||
let err = ctx.send(&mut batch);
|
||||
self.send_worker_set_state(n, SendWorkerState::SentBatch);
|
||||
|
||||
// If err is EAGAIN / EWOULDBLOCK then we clear the readable state
|
||||
// If received is more than zero, we pop and forward those messages
|
||||
@@ -408,14 +444,22 @@ impl<T: AsRawFd + Sync + Send + 'static> SocketIfaceInternal<T> {
|
||||
}
|
||||
|
||||
// Go through the messages and pop / discard all empty messages
|
||||
let mut successfully_sent = 0;
|
||||
while let Some(msg) = batch.pop_front() {
|
||||
if msg.len() > 0 {
|
||||
batch.push_front(msg);
|
||||
break;
|
||||
}
|
||||
successfully_sent += 1;
|
||||
}
|
||||
if successfully_sent == 0 {
|
||||
log::debug!("Worker {n} cycled with no messages sent");
|
||||
}
|
||||
}
|
||||
}
|
||||
fn recv_worker_set_state(self: &Arc<Self>, n: usize, state: RecvWorkerState) {
|
||||
self.recv_worker_states[n].store(state as i32, std::sync::atomic::Ordering::Relaxed);
|
||||
}
|
||||
async fn recv_worker(self: Arc<Self>, n: usize) {
|
||||
let fd_num = n % self.afds.len();
|
||||
let mut ctx: IoContext<RECV_BATCH> = IoContext::new(self.afds[fd_num].as_raw_fd(), self.st);
|
||||
@@ -426,15 +470,19 @@ impl<T: AsRawFd + Sync + Send + 'static> SocketIfaceInternal<T> {
|
||||
msg.allocate_uninitialized(BUFFER_CAP).unwrap();
|
||||
batch.push_back(msg);
|
||||
}
|
||||
self.recv_worker_set_state(n, RecvWorkerState::WaitFdReadable);
|
||||
let mut readable = match self.afds[fd_num].readable().await {
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
self.recv_worker_set_state(n, RecvWorkerState::WaitFdError);
|
||||
log::info!("Error polling fd.readable(): {e} - sleep 1 second");
|
||||
tokio::time::sleep(Duration::from_secs(1)).await;
|
||||
continue;
|
||||
}
|
||||
};
|
||||
self.recv_worker_set_state(n, RecvWorkerState::RecvBatch);
|
||||
let (received, err) = ctx.recv(&mut batch);
|
||||
self.recv_worker_set_state(n, RecvWorkerState::RecievedBatch);
|
||||
// If err is EAGAIN / EWOULDBLOCK then we clear the readable state
|
||||
// If received is more than zero, we pop and forward those messages
|
||||
// If err is EINTER then we ignore and repeat
|
||||
@@ -463,6 +511,7 @@ impl<T: AsRawFd + Sync + Send + 'static> SocketIfaceInternal<T> {
|
||||
continue;
|
||||
}
|
||||
let mlen = msg.len();
|
||||
self.recv_worker_set_state(n, RecvWorkerState::IfaceSend);
|
||||
match self.iface.send(msg) {
|
||||
Ok(()) => {
|
||||
log::trace!("Socket receiver thread sent packet of len {mlen}");
|
||||
@@ -479,6 +528,7 @@ impl<T: AsRawFd + Sync + Send + 'static> SocketIfaceInternal<T> {
|
||||
//
|
||||
// Without yielding here, this can go into a busyloop because none of the
|
||||
// awaits here are actually waiting at all.
|
||||
self.recv_worker_set_state(n, RecvWorkerState::Yield);
|
||||
tokio::task::yield_now().await;
|
||||
}
|
||||
} else {
|
||||
@@ -489,10 +539,38 @@ impl<T: AsRawFd + Sync + Send + 'static> SocketIfaceInternal<T> {
|
||||
}
|
||||
}
|
||||
|
||||
trait SocketIfaceInternalT: Send + Sync {
|
||||
fn worker_states(&self) -> (Vec<SendWorkerState>,Vec<RecvWorkerState>);
|
||||
}
|
||||
impl<T: AsRawFd + Sync + Send> SocketIfaceInternalT for SocketIfaceInternal<T> {
|
||||
fn worker_states(&self) -> (Vec<SendWorkerState>,Vec<RecvWorkerState>) {
|
||||
let mut rout = Vec::with_capacity(self.recv_worker_states.len());
|
||||
let mut sout = Vec::with_capacity(self.send_worker_states.len());
|
||||
for r in &self.recv_worker_states {
|
||||
let n = r.load(std::sync::atomic::Ordering::Relaxed);
|
||||
let x = match RecvWorkerState::try_from(n) {
|
||||
Ok(x) => x,
|
||||
Err(_) => RecvWorkerState::Invalid,
|
||||
};
|
||||
rout.push(x);
|
||||
}
|
||||
for s in &self.send_worker_states {
|
||||
let n = s.load(std::sync::atomic::Ordering::Relaxed);
|
||||
let x = match SendWorkerState::try_from(n) {
|
||||
Ok(x) => x,
|
||||
Err(_) => SendWorkerState::Invalid,
|
||||
};
|
||||
sout.push(x);
|
||||
}
|
||||
(sout, rout)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SocketIface {
|
||||
pub iface: Iface,
|
||||
// This is never sent to, it is DROPPED in order to cause the tasks to exit
|
||||
_done: tokio::sync::broadcast::Sender<()>,
|
||||
inner: Arc<dyn SocketIfaceInternalT>,
|
||||
}
|
||||
impl Drop for SocketIface {
|
||||
fn drop(&mut self) {
|
||||
@@ -513,15 +591,6 @@ impl SocketIface {
|
||||
let (_done, done_r) =
|
||||
tokio::sync::broadcast::channel(1);
|
||||
let (mut iface, iface_pvt) = iface::new("SocketIface");
|
||||
let out: Arc<SocketIfaceInternal<T>> = Arc::new(SocketIfaceInternal {
|
||||
iface: iface_pvt,
|
||||
afds,
|
||||
st,
|
||||
to_go_out_recv: Mutex::new(tgo_r),
|
||||
to_go_out_send: tgo,
|
||||
done_r,
|
||||
});
|
||||
iface.set_receiver(Arc::clone(&out));
|
||||
|
||||
// Lets assume that in general, we're going to have 2 interfaces with one receiving
|
||||
// and the other one sending, both as fast as they can... e.g. TUN / UDP
|
||||
@@ -531,11 +600,28 @@ impl SocketIface {
|
||||
n if n < fds.len() => fds.len(),
|
||||
n => n,
|
||||
};
|
||||
|
||||
let out: Arc<SocketIfaceInternal<T>> = Arc::new(SocketIfaceInternal {
|
||||
iface: iface_pvt,
|
||||
afds,
|
||||
st,
|
||||
to_go_out_recv: Mutex::new(tgo_r),
|
||||
to_go_out_send: tgo,
|
||||
done_r,
|
||||
send_worker_states: (0..workers).map(|_|AtomicI32::new(0)).collect(),
|
||||
recv_worker_states: (0..workers).map(|_|AtomicI32::new(0)).collect(),
|
||||
});
|
||||
iface.set_receiver(Arc::clone(&out));
|
||||
|
||||
for i in 0..workers {
|
||||
tokio::task::spawn(Arc::clone(&out).worker(i, true));
|
||||
tokio::task::spawn(Arc::clone(&out).worker(i, false));
|
||||
}
|
||||
|
||||
Ok(Self{ iface, _done })
|
||||
Ok(Self{ iface, _done, inner: out, })
|
||||
}
|
||||
|
||||
pub fn worker_states(&self) -> (Vec<SendWorkerState>,Vec<RecvWorkerState>) {
|
||||
self.inner.worker_states()
|
||||
}
|
||||
}
|
@@ -1,9 +1,11 @@
|
||||
use num_enum::{IntoPrimitive, TryFromPrimitive};
|
||||
use socket2::{Domain, Protocol, SockAddr, Type};
|
||||
use tokio::net::UdpSocket;
|
||||
use tokio::sync::mpsc::{Receiver, Sender};
|
||||
use tokio::sync::Mutex;
|
||||
use crate::util::sockaddr::Sockaddr;
|
||||
use std::convert::TryFrom;
|
||||
use std::sync::atomic::AtomicI32;
|
||||
use std::sync::Arc;
|
||||
use crate::interface::wire::message::Message;
|
||||
use crate::external::interface::iface::{self, IfRecv, Iface, IfacePvt};
|
||||
@@ -19,7 +21,26 @@ const INCOMING_QUEUE: usize = 64;
|
||||
const BUFFER_CAP: usize = 3496;
|
||||
const PADDING_AMOUNT: usize = 512;
|
||||
|
||||
const WORKERS: usize = 16;
|
||||
#[derive(Debug,IntoPrimitive,TryFromPrimitive)]
|
||||
#[repr(i32)]
|
||||
pub enum SendWorkerState {
|
||||
Invalid = -1,
|
||||
Initializing = 0,
|
||||
WaitLock = 1,
|
||||
RecvBatch = 2,
|
||||
SendBatch = 3,
|
||||
}
|
||||
|
||||
#[derive(Debug,IntoPrimitive,TryFromPrimitive)]
|
||||
#[repr(i32)]
|
||||
pub enum RecvWorkerState {
|
||||
Invalid = -1,
|
||||
Initializing = 0,
|
||||
RecvBatch = 1,
|
||||
RecievedBatch = 2,
|
||||
IfaceSendOne = 3,
|
||||
IfaceSendTwo = 4,
|
||||
}
|
||||
|
||||
struct UDPAddrIfaceInternal {
|
||||
iface: IfacePvt,
|
||||
@@ -29,6 +50,9 @@ struct UDPAddrIfaceInternal {
|
||||
|
||||
incoming_recv: Mutex<Receiver<Message>>,
|
||||
incoming_send: Sender<Message>,
|
||||
|
||||
send_worker_states: Vec<AtomicI32>,
|
||||
recv_worker_states: Vec<AtomicI32>,
|
||||
}
|
||||
impl IfRecv for Arc<UDPAddrIfaceInternal> {
|
||||
fn recv(&self, mut m: Message) -> Result<()> {
|
||||
@@ -41,18 +65,24 @@ impl IfRecv for Arc<UDPAddrIfaceInternal> {
|
||||
}
|
||||
}
|
||||
impl UDPAddrIfaceInternal {
|
||||
async fn send_worker(self: Arc<Self>) {
|
||||
fn send_worker_set_state(self: &Arc<Self>, n: usize, state: SendWorkerState) {
|
||||
self.send_worker_states[n].store(state as i32, std::sync::atomic::Ordering::Relaxed);
|
||||
}
|
||||
async fn send_worker(self: Arc<Self>, n: usize) {
|
||||
let mut send_msgs = Vec::with_capacity(SEND_MSGS_LIMIT);
|
||||
loop {
|
||||
self.send_worker_set_state(n, SendWorkerState::WaitLock);
|
||||
let mut tgo = self.to_go_out_recv.lock().await;
|
||||
self.send_worker_set_state(n, SendWorkerState::RecvBatch);
|
||||
tgo.recv_many(&mut send_msgs, SEND_MSGS_LIMIT).await;
|
||||
drop(tgo);
|
||||
drop(tgo);
|
||||
self.send_worker_set_state(n, SendWorkerState::SendBatch);
|
||||
for (msg, sa) in send_msgs.drain(..) {
|
||||
// println!("got message with length: {}", msg.len());
|
||||
let bytes = msg.bytes();
|
||||
match self.udp.send_to(bytes, sa).await {
|
||||
match self.udp.send_to(bytes, &sa).await {
|
||||
Ok(_) => {
|
||||
// println!("sent message ok");
|
||||
log::trace!("Message to {sa} sent ok");
|
||||
},
|
||||
Err(e) => {
|
||||
log::info!("Unable to send message (len: {}): {e} to: {}",
|
||||
@@ -62,7 +92,10 @@ impl UDPAddrIfaceInternal {
|
||||
}
|
||||
}
|
||||
}
|
||||
async fn recv_worker(self: Arc<Self>) {
|
||||
fn recv_worker_set_state(self: &Arc<Self>, n: usize, state: RecvWorkerState) {
|
||||
self.recv_worker_states[n].store(state as i32, std::sync::atomic::Ordering::Relaxed);
|
||||
}
|
||||
async fn recv_worker(self: Arc<Self>, n: usize) {
|
||||
let mut recv_msgs = Vec::with_capacity(RECV_MSGS_LIMIT);
|
||||
let mut message = None;
|
||||
loop {
|
||||
@@ -75,8 +108,10 @@ impl UDPAddrIfaceInternal {
|
||||
msg.allocate_uninitialized(BUFFER_CAP).unwrap();
|
||||
msg
|
||||
};
|
||||
self.recv_worker_set_state(n, RecvWorkerState::RecvBatch);
|
||||
tokio::select! {
|
||||
res = self.udp.recv_from(msg.bytes_mut()) => {
|
||||
self.recv_worker_set_state(n, RecvWorkerState::RecievedBatch);
|
||||
log::trace!("recv_worker got a recv_from");
|
||||
match res {
|
||||
Ok((byte_count,from)) => {
|
||||
@@ -102,10 +137,12 @@ impl UDPAddrIfaceInternal {
|
||||
}
|
||||
}
|
||||
mut recv = self.incoming_recv.lock() => {
|
||||
self.recv_worker_set_state(n, RecvWorkerState::IfaceSendOne);
|
||||
message = Some(msg);
|
||||
log::trace!("{:?} UDP receiver thread waiting", self.udp.local_addr());
|
||||
recv.recv_many(&mut recv_msgs, RECV_MSGS_LIMIT).await;
|
||||
log::trace!("UDP receiver thread got recv_many");
|
||||
self.recv_worker_set_state(n, RecvWorkerState::IfaceSendTwo);
|
||||
for msg in recv_msgs.drain(..) {
|
||||
match self.iface.send(msg) {
|
||||
Ok(()) => {
|
||||
@@ -146,6 +183,15 @@ impl UDPAddrIface {
|
||||
tokio::sync::mpsc::channel(TO_GO_OUT_QUEUE);
|
||||
let (incoming, incoming_r) =
|
||||
tokio::sync::mpsc::channel(INCOMING_QUEUE);
|
||||
|
||||
let workers = num_cpus::get();
|
||||
let workers = if workers < 2 {
|
||||
log::warn!("UDPAddrIface WORKERS = {workers} is too few, using 2");
|
||||
2
|
||||
} else {
|
||||
workers
|
||||
};
|
||||
|
||||
let internal = Arc::new(UDPAddrIfaceInternal {
|
||||
iface: iface_pvt,
|
||||
udp,
|
||||
@@ -153,19 +199,14 @@ impl UDPAddrIface {
|
||||
to_go_out_send: tgo,
|
||||
incoming_recv: Mutex::new(incoming_r),
|
||||
incoming_send: incoming,
|
||||
send_worker_states: (0..workers).map(|_|AtomicI32::new(0)).collect(),
|
||||
recv_worker_states: (0..workers).map(|_|AtomicI32::new(0)).collect(),
|
||||
});
|
||||
iface.set_receiver(Arc::clone(&internal));
|
||||
|
||||
let workers = WORKERS;
|
||||
let workers = if workers < 2 {
|
||||
log::warn!("UDPAddrIface WORKERS = {workers} is too few, using 2");
|
||||
2
|
||||
} else {
|
||||
workers
|
||||
};
|
||||
for _ in 0..workers {
|
||||
tokio::task::spawn(Arc::clone(&internal).recv_worker());
|
||||
tokio::task::spawn(Arc::clone(&internal).send_worker());
|
||||
for i in 0..workers {
|
||||
tokio::task::spawn(Arc::clone(&internal).recv_worker(i));
|
||||
tokio::task::spawn(Arc::clone(&internal).send_worker(i));
|
||||
}
|
||||
Ok((
|
||||
UDPAddrIface{
|
||||
@@ -204,4 +245,26 @@ impl UDPAddrIface {
|
||||
let bfd = self.internal.udp.as_fd();
|
||||
bfd.as_raw_fd()
|
||||
}
|
||||
|
||||
pub fn worker_states(&self) -> (Vec<SendWorkerState>,Vec<RecvWorkerState>) {
|
||||
let mut rout = Vec::with_capacity(self.internal.recv_worker_states.len());
|
||||
let mut sout = Vec::with_capacity(self.internal.send_worker_states.len());
|
||||
for r in &self.internal.recv_worker_states {
|
||||
let n = r.load(std::sync::atomic::Ordering::Relaxed);
|
||||
let x = match RecvWorkerState::try_from(n) {
|
||||
Ok(x) => x,
|
||||
Err(_) => RecvWorkerState::Invalid,
|
||||
};
|
||||
rout.push(x);
|
||||
}
|
||||
for s in &self.internal.send_worker_states {
|
||||
let n = s.load(std::sync::atomic::Ordering::Relaxed);
|
||||
let x = match SendWorkerState::try_from(n) {
|
||||
Ok(x) => x,
|
||||
Err(_) => SendWorkerState::Invalid,
|
||||
};
|
||||
sout.push(x);
|
||||
}
|
||||
(sout, rout)
|
||||
}
|
||||
}
|
@@ -1,7 +1,7 @@
|
||||
use std::{borrow::Cow, collections::BTreeMap};
|
||||
|
||||
use anyhow::{anyhow, bail, Result};
|
||||
use bendy::value::Value;
|
||||
use cjdns_bencode::bendy::value::Value;
|
||||
|
||||
use crate::{
|
||||
cffi::{
|
||||
|
@@ -1,6 +1,8 @@
|
||||
use crate::cffi::{Allocator_t, Sockaddr_t, Iface_t};
|
||||
use cjdns_bencode::BValue;
|
||||
|
||||
use crate::cffi::{Allocator_t, Dict_t, Iface_t, Object_t, Sockaddr_t};
|
||||
use crate::external::interface::cif;
|
||||
use crate::rffi::allocator;
|
||||
use crate::rffi::{allocator, benc};
|
||||
use crate::rtypes::RTypes_Error_t;
|
||||
use std::os::raw::c_char;
|
||||
use crate::util::sockaddr::Sockaddr;
|
||||
@@ -35,6 +37,37 @@ pub extern "C" fn Rffi_udpIfaceSetBroadcast(iface: *mut Rffi_UDPIface_pvt, broad
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Rffi_udpIface_worker_states(
|
||||
outP: *mut *mut Object_t,
|
||||
iface: *mut Rffi_UDPIface_pvt,
|
||||
alloc: *mut Allocator_t,
|
||||
) -> *mut RTypes_Error_t {
|
||||
let (sws, rws) = from_c!(iface).udp.worker_states();
|
||||
let bv = BValue::builder()
|
||||
.set_dict()
|
||||
.add_dict_entry("send", |mut b|{
|
||||
b = b.set_dict();
|
||||
for (i, s) in sws.iter().enumerate() {
|
||||
b = b.add_dict_entry(i.to_string(), |b|b.set_str(format!("{s:?}")));
|
||||
}
|
||||
b
|
||||
})
|
||||
.add_dict_entry("recv", |mut b|{
|
||||
b = b.set_dict();
|
||||
for (i, r) in rws.iter().enumerate() {
|
||||
b = b.add_dict_entry(i.to_string(), |b|b.set_str(format!("{r:?}")));
|
||||
}
|
||||
b
|
||||
})
|
||||
.build();
|
||||
let out = benc::value_to_c(alloc, bv.inner());
|
||||
unsafe {
|
||||
*outP = out;
|
||||
}
|
||||
std::ptr::null_mut()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Rffi_udpIfaceSetDscp(iface: *mut Rffi_UDPIface_pvt, dscp: u8) -> i32 {
|
||||
match from_c!(iface).udp.set_dscp(dscp) {
|
||||
|
@@ -1,7 +1,5 @@
|
||||
use crate::cffi::{
|
||||
Allocator_t,
|
||||
Iface_t,
|
||||
Sockaddr_t
|
||||
Allocator_t, Dict_t, Iface_t, Object_t, Sockaddr_t
|
||||
};
|
||||
use crate::external::interface::cif;
|
||||
use crate::gcl::Protected;
|
||||
@@ -9,8 +7,9 @@ use crate::interface::{
|
||||
socketiface::{SocketIface, SocketType},
|
||||
unixsocketiface::{UnixSocketClient, UnixSocketServer}
|
||||
};
|
||||
use crate::rffi::allocator;
|
||||
use crate::rtypes::RTypes_Error_t;
|
||||
use crate::rffi::{allocator, benc};
|
||||
use crate::rtypes::{RTypes_Error_t, RTypes_SocketType};
|
||||
use crate::util::identity::from_c_const;
|
||||
use crate::util::{
|
||||
callable::Callable,
|
||||
identity::{from_c, Identity},
|
||||
@@ -18,6 +17,7 @@ use crate::util::{
|
||||
};
|
||||
use std::sync::Arc;
|
||||
use anyhow::anyhow;
|
||||
use cjdns_bencode::BValue;
|
||||
use libc::c_char;
|
||||
use std::ffi::CStr;
|
||||
|
||||
@@ -50,23 +50,52 @@ pub extern "C" fn Rffi_fileExists(
|
||||
out
|
||||
}
|
||||
|
||||
pub struct Rffi_SocketIface_t {
|
||||
si: SocketIface,
|
||||
identity: Identity<Self>,
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Rffi_socketWorkerStates(
|
||||
outP: *mut *mut Object_t,
|
||||
si: *const Rffi_SocketIface_t,
|
||||
alloc: *mut Allocator_t,
|
||||
) -> *mut RTypes_Error_t {
|
||||
let si = from_c_const!(si);
|
||||
let (sws, rws) = si.si.worker_states();
|
||||
|
||||
let bv = BValue::builder()
|
||||
.set_dict()
|
||||
.add_dict_entry("send", |mut b|{
|
||||
b = b.set_dict();
|
||||
for (i, s) in sws.iter().enumerate() {
|
||||
b = b.add_dict_entry(i.to_string(), |b|b.set_str(format!("{s:?}")));
|
||||
}
|
||||
b
|
||||
})
|
||||
.add_dict_entry("recv", |mut b|{
|
||||
b = b.set_dict();
|
||||
for (i, r) in rws.iter().enumerate() {
|
||||
b = b.add_dict_entry(i.to_string(), |b|b.set_str(format!("{r:?}")));
|
||||
}
|
||||
b
|
||||
})
|
||||
.build();
|
||||
let out = benc::value_to_c(alloc, bv.inner());
|
||||
unsafe {
|
||||
*outP = out;
|
||||
}
|
||||
std::ptr::null_mut()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Rffi_socketForFd(
|
||||
ifOut: *mut *mut Iface_t,
|
||||
so_out: *mut *mut Rffi_SocketIface_t,
|
||||
fd: libc::c_int,
|
||||
socket_type: libc::c_int,
|
||||
st: RTypes_SocketType,
|
||||
alloc: *mut Allocator_t,
|
||||
) -> *mut RTypes_Error_t {
|
||||
let st = match socket_type {
|
||||
0 => SocketType::Stream,
|
||||
1 => SocketType::Frames,
|
||||
2 => SocketType::SendToFrames,
|
||||
_ => {
|
||||
return allocator::adopt(alloc, RTypes_Error_t {
|
||||
e: Some(anyhow::anyhow!("Invalid socket type: {socket_type}")),
|
||||
});
|
||||
}
|
||||
};
|
||||
let mut si = match SocketIface::new(vec![ fd ], st) {
|
||||
Ok(si) => si,
|
||||
Err(e) => {
|
||||
@@ -74,9 +103,11 @@ pub extern "C" fn Rffi_socketForFd(
|
||||
}
|
||||
};
|
||||
let out = cif::wrap(alloc, &mut si.iface);
|
||||
allocator::adopt(alloc, si);
|
||||
let sout =
|
||||
allocator::adopt(alloc, Rffi_SocketIface_t{ si, identity: Default::default() });
|
||||
unsafe {
|
||||
*ifOut = out;
|
||||
*so_out = sout;
|
||||
}
|
||||
std::ptr::null_mut()
|
||||
}
|
||||
|
@@ -4,6 +4,7 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use libc::c_char;
|
||||
use num_enum::{IntoPrimitive, TryFromPrimitive};
|
||||
|
||||
use crate::{cffi::{self, Iface_t, String_t}, rffi::event_loop::EventLoop, util::identity::Identity};
|
||||
|
||||
@@ -106,6 +107,14 @@ pub struct RTypes_EventLoop_t {
|
||||
pub identity: Identity<Self>,
|
||||
}
|
||||
|
||||
#[derive(PartialEq,Clone,Copy,IntoPrimitive,TryFromPrimitive)]
|
||||
#[repr(i32)]
|
||||
pub enum RTypes_SocketType {
|
||||
SendToFrames,
|
||||
Frames,
|
||||
Stream,
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[repr(C)]
|
||||
pub struct RTypes_ExportMe {
|
||||
@@ -118,4 +127,5 @@ pub struct RTypes_ExportMe {
|
||||
g: RTypes_CryptoAuth2_TryHandshake_Ret_t,
|
||||
h: RTypes_Seeder_DnsSeeds_t,
|
||||
i: *mut RTypes_EventLoop_t,
|
||||
j: RTypes_SocketType,
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
use bendy::value::Value;
|
||||
use cjdns_bencode::bendy::value::Value;
|
||||
use std::collections::BTreeMap;
|
||||
use std::io::Read;
|
||||
use std::borrow::Cow;
|
||||
@@ -359,7 +359,7 @@ pub fn serialize<'a, W: RWrite>(writer: &mut W, obj: &Value<'a>) -> IoResult<()>
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use anyhow::bail;
|
||||
use bendy::value::Value;
|
||||
use cjdns_bencode::bendy::value::Value;
|
||||
|
||||
use crate::interface::wire::message::Message;
|
||||
|
||||
@@ -676,7 +676,7 @@ mod test {
|
||||
msg.push_bytes(conf.as_bytes()).unwrap();
|
||||
let res = parse(msg, false).unwrap();
|
||||
let _ = match res {
|
||||
bendy::value::Value::Dict(d) => d,
|
||||
cjdns_bencode::bendy::value::Value::Dict(d) => d,
|
||||
_ => panic!("Wrong type"),
|
||||
};
|
||||
}
|
||||
|
@@ -24,12 +24,6 @@
|
||||
#include "util/Linker.h"
|
||||
Linker_require("util/events/libuv/Socket.c")
|
||||
|
||||
#define Socket_forFd_STREAM 0
|
||||
#define Socket_forFd_FRAMES 1
|
||||
#define Socket_forFd_SENDTO_FRAMES 2
|
||||
|
||||
Err_DEFUN Socket_forFd(Iface_t** s, int fd, int socketType, struct Allocator* userAlloc);
|
||||
|
||||
Err_DEFUN Socket_connect(Iface_t** iface, const char* path, Allocator_t* userAlloc);
|
||||
|
||||
typedef struct Socket_Server {
|
||||
|
@@ -18,8 +18,6 @@
|
||||
#include "exception/Err.h"
|
||||
#include "interface/addressable/AddrIface.h"
|
||||
#include "memory/Allocator.h"
|
||||
#include "util/events/EventBase.h"
|
||||
#include "util/log/Log.h"
|
||||
#include "util/Linker.h"
|
||||
Linker_require("util/events/libuv/UDPAddrIface.c")
|
||||
|
||||
@@ -45,10 +43,8 @@ struct UDPAddrIface
|
||||
*/
|
||||
Err_DEFUN UDPAddrIface_new(
|
||||
struct UDPAddrIface** out,
|
||||
EventBase_t* eventBase,
|
||||
struct Sockaddr* addr,
|
||||
struct Allocator* alloc,
|
||||
struct Log* logger);
|
||||
struct Allocator* alloc);
|
||||
|
||||
int UDPAddrIface_setDSCP(struct UDPAddrIface* iface, uint8_t dscp);
|
||||
|
||||
@@ -56,4 +52,9 @@ int UDPAddrIface_setBroadcast(struct UDPAddrIface* iface, bool enable);
|
||||
|
||||
int UDPAddrIface_getFd(struct UDPAddrIface*);
|
||||
|
||||
Err_DEFUN UDPAddrIface_workerStates(
|
||||
Object_t** out,
|
||||
struct UDPAddrIface* iface,
|
||||
Allocator_t* alloc);
|
||||
|
||||
#endif
|
||||
|
@@ -17,11 +17,6 @@
|
||||
#include "util/events/Socket.h"
|
||||
#include "rust/cjdns_sys/Rffi.h"
|
||||
|
||||
Err_DEFUN Socket_forFd(Iface_t** s, int fd, int socketType, struct Allocator* userAlloc)
|
||||
{
|
||||
return Rffi_socketForFd(s, fd, socketType, userAlloc);
|
||||
}
|
||||
|
||||
Err_DEFUN Socket_connect(Iface_t** iface, const char* path, Allocator_t* userAlloc)
|
||||
{
|
||||
return Rffi_unixSocketConnect(iface, path, userAlloc);
|
||||
|
@@ -43,12 +43,19 @@ int UDPAddrIface_setBroadcast(struct UDPAddrIface* iface, bool enable)
|
||||
return (int) Rffi_udpIfaceSetBroadcast(ifp->internal->pvt, enable);
|
||||
}
|
||||
|
||||
Err_DEFUN UDPAddrIface_workerStates(
|
||||
Object_t** out,
|
||||
struct UDPAddrIface* iface,
|
||||
Allocator_t* alloc)
|
||||
{
|
||||
struct UDPAddrIface_pvt* ifp = Identity_check((struct UDPAddrIface_pvt*)iface);
|
||||
return Rffi_udpIface_worker_states(out, ifp->internal->pvt, alloc);
|
||||
}
|
||||
|
||||
Err_DEFUN UDPAddrIface_new(
|
||||
struct UDPAddrIface** outP,
|
||||
EventBase_t* eventBase,
|
||||
struct Sockaddr* addr,
|
||||
struct Allocator* userAlloc,
|
||||
struct Log* logger)
|
||||
struct Allocator* userAlloc)
|
||||
{
|
||||
Rffi_UDPIface* internal = NULL;
|
||||
Err(Rffi_udpIfaceNew(&internal, addr, userAlloc));
|
||||
|
Reference in New Issue
Block a user