0
0
mirror of https://github.com/cjdelisle/cjdns synced 2025-10-06 00:32:50 +02:00
This commit is contained in:
Caleb James DeLisle
2018-08-24 16:57:14 +02:00
parent d602ecd4bb
commit 13e8fe16a9
13 changed files with 122 additions and 28 deletions

View File

@@ -121,6 +121,7 @@ static void sendMessage(struct Message* message, struct Sockaddr* dest, struct A
// stack overflow when used with admin logger.
//Log_keys(admin->logger, "sending message to angel [%s]", message->bytes);
struct AddrIface_Header aihdr = { .recvTime_high = 0 };
Assert_true(dest->addrLen < AddrIface_Header_SIZE);
Bits_memcpy(&aihdr.addr, dest, dest->addrLen);
Message_push(message, &aihdr, AddrIface_Header_SIZE, NULL);
Iface_send(&admin->iface, message);

View File

@@ -73,6 +73,6 @@ struct ETHInterface* ETHInterface_new(struct EventBase* eventBase,
List* ETHInterface_listDevices(struct Allocator* alloc, struct Except* eh);
void ETHInterface_timestampPackets(struct ETHInterface* iface, bool enable);
bool ETHInterface_timestampPackets(struct ETHInterface* iface, bool enable);
#endif

View File

@@ -23,6 +23,10 @@
#include "util/AddrTools.h"
#include "util/Identity.h"
#define ArrayList_TYPE struct ETHInterface
#define ArrayList_NAME ETHInterface
#include "util/ArrayList.h"
struct Context
{
struct EventBase* eventBase;
@@ -30,9 +34,28 @@ struct Context
struct Log* logger;
struct Admin* admin;
struct InterfaceController* ic;
struct ArrayList_ETHInterface* ifaces;
Identity
};
static struct ETHInterface* getIface(struct Context* ctx,
Dict* args,
String* txid,
struct Allocator* requestAlloc,
uint32_t* ifNumP)
{
int64_t* interfaceNumber = Dict_getIntC(args, "interfaceNumber");
uint32_t ifNum = (interfaceNumber) ? ((uint32_t) *interfaceNumber) : 0;
if (ifNumP) { *ifNumP = ifNum; }
struct ETHInterface* ethIf = ArrayList_ETHInterface_get(ctx->ifaces, ifNum);
if (!ethIf) {
Dict* out = Dict_new(requestAlloc);
Dict_putStringCC(out, "error", "no such interface for interfaceNumber", requestAlloc);
Admin_sendMessage(out, txid, ctx->admin);
}
return ethIf;
}
static void beginConnection(Dict* args,
void* vcontext,
String* txid,
@@ -104,6 +127,10 @@ static void newInterface(Dict* args, void* vcontext, String* txid, struct Alloca
struct InterfaceController_Iface* ici = InterfaceController_newIface(ctx->ic, ifname, alloc);
Iface_plumb(&ici->addrIf, &ethIf->generic.iface);
while (ici->ifNum > ctx->ifaces->length) {
ArrayList_ETHInterface_add(ctx->ifaces, NULL);
}
ArrayList_ETHInterface_put(ctx->ifaces, ici->ifNum, ethIf);
Dict* out = Dict_new(requestAlloc);
Dict_putStringCC(out, "error", "none", requestAlloc);
@@ -172,6 +199,28 @@ static void listDevices(Dict* args, void* vcontext, String* txid, struct Allocat
Admin_sendMessage(out, txid, ctx->admin);
}
static void timestampPackets(
Dict* args, void* vcontext, String* txid, struct Allocator* requestAlloc)
{
struct Context* ctx = Identity_check((struct Context*) vcontext);
struct ETHInterface* ethIf = getIface(ctx, args, txid, requestAlloc, NULL);
if (!ethIf) { return; }
int64_t* enable = Dict_getIntC(args, "enable");
bool enabled;
if (!enable) {
enabled = ETHInterface_timestampPackets(ethIf, false);
if (enabled) {
ETHInterface_timestampPackets(ethIf, true);
}
} else {
enabled = ETHInterface_timestampPackets(ethIf, *enable);
}
Dict* out = Dict_new(requestAlloc);
Dict_putStringCC(out, "error", "none", requestAlloc);
Dict_putIntC(out, "enabled", enabled, requestAlloc);
Admin_sendMessage(out, txid, ctx->admin);
}
void ETHInterface_admin_register(struct EventBase* base,
struct Allocator* alloc,
struct Log* logger,
@@ -186,6 +235,7 @@ void ETHInterface_admin_register(struct EventBase* base,
.ic = ic
}));
Identity_set(ctx);
ctx->ifaces = ArrayList_ETHInterface_new(alloc);
Admin_registerFunction("ETHInterface_new", newInterface, ctx, true,
((struct Admin_FunctionArg[]) {
@@ -208,4 +258,10 @@ void ETHInterface_admin_register(struct EventBase* base,
}), admin);
Admin_registerFunction("ETHInterface_listDevices", listDevices, ctx, true, NULL, admin);
Admin_registerFunction("ETHInterface_timestampPackets", timestampPackets, ctx, true,
((struct Admin_FunctionArg[]) {
{ .name = "interfaceNumber", .required = 0, .type = "Int" },
{ .name = "enable", .required = 0, .type = "Int" }
}), admin);
}

View File

@@ -79,7 +79,7 @@ static Iface_DEFUN sendMessage(struct Message* msg, struct Iface* iface)
struct AddrIface_Header aihdr;
Message_pop(msg, &aihdr, AddrIface_Header_SIZE, NULL);
struct Sockaddr* sa = &aihdr.addr.addr;
Assert_true(sa->addrLen == ETHInterface_Sockaddr_SIZE);
Assert_true(sa->addrLen <= ETHInterface_Sockaddr_SIZE);
struct ETHInterface_Sockaddr* sockaddr = (struct ETHInterface_Sockaddr*) sa;
struct ETHInterface_Header hdr = {
@@ -96,6 +96,7 @@ static Iface_DEFUN sendMessage(struct Message* msg, struct Iface* iface)
if (sockaddr->generic.flags & Sockaddr_flags_BCAST) {
Bits_memset(ethFr.dest, 0xff, 6);
} else {
Assert_true(sa->addrLen == ETHInterface_Sockaddr_SIZE);
Bits_memcpy(ethFr.dest, sockaddr->mac, 6);
}
Bits_memcpy(ethFr.src, ctx->myMac, 6);
@@ -269,10 +270,12 @@ static void macaddr(const char* ifname, uint8_t addrOut[6], struct Except* eh)
Except_throw(eh, "Could not find mac address for [%s]", ifname);
}
void ETHInterface_timestampPackets(struct ETHInterface* iface, bool enable)
bool ETHInterface_timestampPackets(struct ETHInterface* iface, bool enable)
{
struct ETHInterface_pvt* context = Identity_check((struct ETHInterface_pvt*) iface);
bool out = context->timestampPackets;
context->timestampPackets = enable;
return out;
}
struct ETHInterface* ETHInterface_new(struct EventBase* eventBase,

View File

@@ -120,6 +120,7 @@ static Iface_DEFUN sendMessage(struct Message* msg, struct Iface* iface)
if (sockaddr->generic.flags & Sockaddr_flags_BCAST) {
Bits_memset(addr.sll_addr, 0xff, 6);
} else {
Assert_true(sa->addrLen == ETHInterface_Sockaddr_SIZE);
Bits_memcpy(addr.sll_addr, sockaddr->mac, 6);
}
@@ -239,10 +240,12 @@ static int closeSocket(struct Allocator_OnFreeJob* j)
return 0;
}
void ETHInterface_timestampPackets(struct ETHInterface* iface, bool enable)
bool ETHInterface_timestampPackets(struct ETHInterface* iface, bool enable)
{
struct ETHInterface_pvt* context = Identity_check((struct ETHInterface_pvt*) iface);
bool out = context->timestampPackets;
context->timestampPackets = enable;
return out;
}
struct ETHInterface* ETHInterface_new(struct EventBase* eventBase,

View File

@@ -158,18 +158,13 @@ static Iface_DEFUN fromBcastSock(struct Message* m, struct Iface* iface)
struct UDPInterface_pvt* ctx =
Identity_containerOf(iface, struct UDPInterface_pvt, bcastSock);
if (m->length < UDPInterface_BroadcastHeader_SIZE + Sockaddr_OVERHEAD) {
if (m->length < UDPInterface_BroadcastHeader_SIZE + UDPInterface_BroadcastHeader_SIZE) {
Log_debug(ctx->log, "DROP runt bcast");
return NULL;
}
struct Sockaddr_storage ss;
Message_pop(m, &ss, Sockaddr_OVERHEAD, NULL);
if (m->length < UDPInterface_BroadcastHeader_SIZE + ss.addr.addrLen - Sockaddr_OVERHEAD) {
Log_debug(ctx->log, "DROP runt bcast");
return NULL;
}
Message_pop(m, &ss.nativeAddr, ss.addr.addrLen - Sockaddr_OVERHEAD, NULL);
struct AddrIface_Header aihdr;
Message_pop(m, &aihdr, AddrIface_Header_SIZE, NULL);
struct UDPInterface_BroadcastHeader hdr;
Message_pop(m, &hdr, UDPInterface_BroadcastHeader_SIZE, NULL);
@@ -193,10 +188,10 @@ static Iface_DEFUN fromBcastSock(struct Message* m, struct Iface* iface)
uint16_t commPort = Endian_bigEndianToHost16(hdr.commPort_be);
// Fake that it came from the communication port
Sockaddr_setPort(&ss.addr, commPort);
ss.addr.flags |= Sockaddr_flags_BCAST;
Sockaddr_setPort(&aihdr.addr.addr, commPort);
aihdr.addr.addr.flags |= Sockaddr_flags_BCAST;
Message_push(m, &ss.addr, ss.addr.addrLen, NULL);
Message_push(m, &aihdr, AddrIface_Header_SIZE, NULL);
return Iface_next(&ctx->pub.generic.iface, m);
}
@@ -218,8 +213,6 @@ struct UDPInterface* UDPInterface_new(struct EventBase* eventBase,
struct UDPAddrIface* uai = UDPAddrIface_new(eventBase, bindAddr, alloc, exHandler, logger);
UDPAddrIface_timestampPackets(uai, true);
uint16_t commPort = Sockaddr_getPort(uai->generic.addr);
struct UDPInterface_pvt* context = Allocator_calloc(alloc, sizeof(struct UDPInterface_pvt), 1);
@@ -311,8 +304,8 @@ int UDPInterface_setDSCP(struct UDPInterface* udpif, uint8_t dscp)
return 0;
}
void UDPInterface_timestampPackets(struct UDPInterface* udpif, bool enable)
bool UDPInterface_timestampPackets(struct UDPInterface* udpif, bool enable)
{
struct UDPInterface_pvt* ctx = Identity_check((struct UDPInterface_pvt*) udpif);
UDPAddrIface_timestampPackets(ctx->commIf, enable);
return UDPAddrIface_timestampPackets(ctx->commIf, enable);
}

View File

@@ -115,10 +115,9 @@ List* UDPInterface_getBroadcastAddrs(struct UDPInterface* udpif, struct Allocato
int UDPInterface_setDSCP(struct UDPInterface* udpif, uint8_t dscp);
/**
* If set to true, received packets will have a 64 bit high resolution timestamp prepended
* to the data after the address is prepended. Sent packets are expected to have no such
* thing and it is the duty of the caller to remove the timestamp before re-sending.
* If set to true, received packets will have a 64 bit high resolution timestamp.
* See AddrIface_Header in AddrIface.h for more information.
*/
void UDPInterface_timestampPackets(struct UDPInterface* idpif, bool enable);
bool UDPInterface_timestampPackets(struct UDPInterface* idpif, bool enable);
#endif

View File

@@ -190,6 +190,9 @@ static void newInterface2(struct Context* ctx,
struct InterfaceController_Iface* ici =
InterfaceController_newIface(ctx->ic, name, alloc);
Iface_plumb(&ici->addrIf, &udpif->generic.iface);
while (ici->ifNum > ctx->ifaces->length) {
ArrayList_UDPInterface_add(ctx->ifaces, NULL);
}
ArrayList_UDPInterface_put(ctx->ifaces, ici->ifNum, udpif);
Dict* out = Dict_new(requestAlloc);
@@ -315,6 +318,28 @@ static void beacon(Dict* args, void* vcontext, String* txid, struct Allocator* r
Admin_sendMessage(&out, txid, ctx->admin);
}
static void timestampPackets(
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);
if (!udpIf) { return; }
int64_t* enable = Dict_getIntC(args, "enable");
bool enabled;
if (!enable) {
enabled = UDPInterface_timestampPackets(udpIf, false);
if (enabled) {
UDPInterface_timestampPackets(udpIf, true);
}
} else {
enabled = UDPInterface_timestampPackets(udpIf, *enable);
}
Dict* out = Dict_new(requestAlloc);
Dict_putStringCC(out, "error", "none", requestAlloc);
Dict_putIntC(out, "enabled", enabled, requestAlloc);
Admin_sendMessage(out, txid, ctx->admin);
}
void UDPInterface_admin_register(struct EventBase* base,
struct Allocator* alloc,
struct Log* logger,
@@ -374,4 +399,10 @@ void UDPInterface_admin_register(struct EventBase* base,
{ .name = "interfaceNumber", .required = 0, .type = "Int" },
{ .name = "state", .required = 0, .type = "Int" }
}), admin);
Admin_registerFunction("UDPInterface_timestampPackets", timestampPackets, ctx, true,
((struct Admin_FunctionArg[]) {
{ .name = "interfaceNumber", .required = 0, .type = "Int" },
{ .name = "enable", .required = 0, .type = "Int" }
}), admin);
}

View File

@@ -99,6 +99,7 @@ static Iface_DEFUN incomingFromHeaderIf(struct Message* message, struct Iface* i
Message_shift(message, -(Headers_IP6Header_SIZE + Headers_UDPHeader_SIZE), NULL);
struct AddrIface_Header aihdr = { .recvTime_high = 0 };
Assert_true(addr->addrLen < AddrIface_Header_SIZE);
Bits_memcpy(&aihdr.addr, addr, addr->addrLen);
Message_push(message, &aihdr, AddrIface_Header_SIZE, NULL);

View File

@@ -495,6 +495,7 @@ static Iface_DEFUN sendFromSwitch(struct Message* msg, struct Iface* switchIf)
Assert_true(!(((uintptr_t)msg->bytes) % 4) && "alignment fault");
struct AddrIface_Header aihdr = { .recvTime_high = 0 };
Assert_true(ep->lladdr->addrLen < AddrIface_Header_SIZE);
Bits_memcpy(&aihdr.addr, ep->lladdr, ep->lladdr->addrLen);
Message_push(msg, &aihdr, AddrIface_Header_SIZE, NULL);
@@ -531,6 +532,7 @@ static int closeInterface(struct Allocator_OnFreeJob* job)
static Iface_DEFUN handleBeacon(struct Message* msg, struct InterfaceController_Iface_pvt* ici)
{
struct InterfaceController_pvt* ic = ici->ic;
Log_debug(ic->logger, "Handle beacon");
if (!ici->pub.beaconState) {
// accepting beacons disabled.
Log_debug(ic->logger, "[%s] Dropping beacon because beaconing is disabled",
@@ -644,7 +646,7 @@ static Iface_DEFUN handleUnexpectedIncoming(struct Message* msg,
struct InterfaceController_Iface_pvt* ici)
{
struct InterfaceController_pvt* ic = ici->ic;
Log_debug(ic->logger, "handleUnexpectedIncoming()");
struct AddrIface_Header* aihdr = (struct AddrIface_Header*) msg->bytes;
struct Sockaddr* lladdr = &aihdr->addr.addr;
Message_shift(msg, -AddrIface_Header_SIZE, NULL);
@@ -741,6 +743,8 @@ static Iface_DEFUN handleIncomingFromWire(struct Message* msg, struct Iface* add
}
uint64_t recvTime = ((uint64_t)aihdr->recvTime_high << 32) | aihdr->recvTime_low;
uint64_t now = Time_hrtime();
Log_debug(ici->ic->logger, "DELTA-T %llu", ((long long) now) - recvTime);
if (Defined(Log_DEBUG) && recvTime) {
if (ici->ic->lastPeer == ep
&& ici->ic->lastNonce + 1 == nonce

View File

@@ -140,8 +140,8 @@ struct InterfaceController_Iface
* @param alloc an allocator, the interface will be removed when this is freed.
*/
struct InterfaceController_Iface* InterfaceController_newIface(struct InterfaceController* ifc,
String* name,
struct Allocator* alloc);
String* name,
struct Allocator* alloc);
/** Get the number of interfaces registered with the controller. */
int InterfaceController_ifaceCount(struct InterfaceController* ifc);

View File

@@ -55,6 +55,6 @@ int UDPAddrIface_setDSCP(struct UDPAddrIface* iface, uint8_t dscp);
int UDPAddrIface_setBroadcast(struct UDPAddrIface* iface, bool enable);
void UDPAddrIface_timestampPackets(struct UDPAddrIface* iface, bool enable);
bool UDPAddrIface_timestampPackets(struct UDPAddrIface* iface, bool enable);
#endif

View File

@@ -171,6 +171,7 @@ static void incoming(uv_udp_t* handle,
struct AddrIface_Header* hdr = (struct AddrIface_Header*) m->bytes;
Bits_memset(hdr, 0, sizeof(struct AddrIface_Header));
Bits_memcpy(&hdr->addr.addr, context->pub.generic.addr, Sockaddr_OVERHEAD);
Assert_true(context->pub.generic.addr->addrLen < Sockaddr_MAXSIZE);
Bits_memcpy(&hdr->addr.nativeAddr, addr, context->pub.generic.addr->addrLen);
// make sure the sockaddr doesn't have crap in it which will
@@ -270,10 +271,12 @@ int UDPAddrIface_setBroadcast(struct UDPAddrIface* iface, bool enable)
return uv_udp_set_broadcast(&context->uvHandle, enable ? 1 : 0);
}
void UDPAddrIface_timestampPackets(struct UDPAddrIface* iface, bool enable)
bool UDPAddrIface_timestampPackets(struct UDPAddrIface* iface, bool enable)
{
struct UDPAddrIface_pvt* context = Identity_check((struct UDPAddrIface_pvt*) iface);
bool out = context->timestampPackets;
context->timestampPackets = enable;
return out;
}
struct UDPAddrIface* UDPAddrIface_new(struct EventBase* eventBase,