mirror of
https://github.com/cjdelisle/cjdns
synced 2025-10-06 00:32:50 +02:00
wip
This commit is contained in:
@@ -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);
|
||||
|
@@ -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
|
||||
|
@@ -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, ðIf->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);
|
||||
}
|
||||
|
@@ -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,
|
||||
|
@@ -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,
|
||||
|
@@ -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);
|
||||
}
|
@@ -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
|
@@ -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);
|
||||
}
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
|
@@ -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
|
||||
|
@@ -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,
|
||||
|
Reference in New Issue
Block a user