0
0
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:
Caleb James DeLisle
2024-09-28 15:09:17 +02:00
parent fe5c6ac21d
commit b6d49b39c1
43 changed files with 645 additions and 777 deletions

38
Cargo.lock generated
View File

@@ -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"

View File

@@ -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"

View File

@@ -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);

View File

@@ -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 */

View File

@@ -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.
*

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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(&ethertype, 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;
}

View File

@@ -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(&ethertype, 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;
}

View File

@@ -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

View File

@@ -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, &eth, 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(&etherType, 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, &eth, 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;
}

View File

@@ -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

View 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);
}

View File

@@ -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

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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

View File

@@ -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) {

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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 }

View File

@@ -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 */

View File

@@ -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);

View File

@@ -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()
}
}

View File

@@ -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)
}
}

View File

@@ -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::{

View File

@@ -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) {

View File

@@ -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()
}

View File

@@ -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,
}

View File

@@ -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"),
};
}

View File

@@ -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 {

View File

@@ -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

View File

@@ -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);

View File

@@ -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));