static uint8_t sendMessage(struct Message* message, struct Interface* ethIf) { struct ETHInterface* context = Identity_cast((struct ETHInterface*) ethIf); struct sockaddr_ll addr; Bits_memcpyConst(&addr, &context->addrBase, sizeof(struct sockaddr_ll)); Message_pop(message, addr.sll_addr, 8); /* Cut down on the noise uint8_t buff[sizeof(addr) * 2 + 1] = {0}; Hex_encode(buff, sizeof(buff), (uint8_t*)&addr, sizeof(addr)); Log_debug(context->logger, "Sending ethernet frame to [%s]", buff); */ // Check if we will have to pad the message and pad if necessary. int pad = 0; for (int length = message->length; length+2 < MIN_PACKET_SIZE; length += 8) { pad++; } if (pad > 0) { int length = message->length; Message_shift(message, pad*8); Bits_memset(message->bytes, 0, pad*8); Bits_memmove(message->bytes, &message->bytes[pad*8], length); } Assert_true(pad < 8); uint16_t padAndId_be = Endian_hostToBigEndian16((context->id << 3) | pad); Message_push(message, &padAndId_be, 2); if (sendto(context->socket, message->bytes, message->length, 0, (struct sockaddr*) &addr, sizeof(struct sockaddr_ll)) < 0) { switch (errno) { case EMSGSIZE: return Error_OVERSIZE_MESSAGE; case ENOBUFS: case EAGAIN: return Error_LINK_LIMIT_EXCEEDED; default:; Log_info(context->logger, "Got error sending to socket [%s]", strerror(errno)); } } return 0; }
static int closeInterface(struct Allocator_OnFreeJob* job) { struct IFCPeer* toClose = Identity_cast((struct IFCPeer*) job->userData); struct Context* ic = ifcontrollerForPeer(toClose); // flush the peer from the table... RouterModule_brokenPath(toClose->switchLabel, ic->routerModule); int index = Map_OfIFCPeerByExernalIf_indexForHandle(toClose->handle, &ic->peerMap); Assert_true(index >= 0); Map_OfIFCPeerByExernalIf_remove(index, &ic->peerMap); return 0; }
static struct Address* getWorst(struct RumorMill_pvt* rm) { struct Address* worst = NULL; int howBadIsTheWorst = 0; for (int i = 0; i < rm->pub.count; i++) { int howBad = getBadness(&rm->pub.addresses[i], rm->selfAddr); if (howBad > howBadIsTheWorst) { howBadIsTheWorst = howBad; worst = &rm->pub.addresses[i]; } } Assert_true(worst); return worst; }
static void disconnectAdopted(struct Allocator_pvt* parent, struct Allocator_pvt* child) { Assert_true(parent->adoptions); Assert_true(parent->adoptions->children); Assert_true(child->adoptions); Assert_true(child->adoptions->parents); Assert_true(disconnectAllocator(child, &parent->adoptions->children)); Assert_true(disconnectAllocator(parent, &child->adoptions->parents)); }
void AddrTools_printShortIp(uint8_t output[40], const uint8_t binIp[16]) { /* The chances of hitting :0:0: and breaking * RFC5952 are 1 in (1 / (2^16))^2 * 6. * E. Siler */ char *p = output; int i = 0; for (; i < 16;) { if ((size_t)p != (size_t)output) { *p++= ':'; } if (binIp[i] > 0x0F) { Hex_encode(p, 2, &binIp[i++], 1); p += 2; } else if (binIp[i] > 0x00) { *p++ = Hex_encodeLowNibble(binIp[i++]); } else { ++i; if (binIp[i] > 0x0F) { Hex_encode(p, 2, &binIp[i++], 1); p += 2; } else { *p++ = Hex_encodeLowNibble(binIp[i++]); } continue; } Hex_encode(p, 2, &binIp[i++], 1); p += 2; } *p = '\0'; Assert_true((size_t)p <= ((size_t)output + 40)); Assert_true(i <= 16); }
static Iface_DEFUN handleIncomingFromWire(struct Message* msg, struct Iface* addrIf) { struct InterfaceController_Iface_pvt* ici = Identity_containerOf(addrIf, struct InterfaceController_Iface_pvt, pub.addrIf); struct Sockaddr* lladdr = (struct Sockaddr*) msg->bytes; if (msg->length < Sockaddr_OVERHEAD || msg->length < lladdr->addrLen) { Log_debug(ici->ic->logger, "DROP runt"); return NULL; } Assert_true(!((uintptr_t)msg->bytes % 4) && "alignment fault"); Assert_true(!((uintptr_t)lladdr->addrLen % 4) && "alignment fault"); // noisy if (Defined(Log_DEBUG) && false) { char* printedAddr = Hex_print(&lladdr[1], lladdr->addrLen - Sockaddr_OVERHEAD, msg->alloc); Log_debug(ici->ic->logger, "Incoming message from [%s]", printedAddr); } if (lladdr->flags & Sockaddr_flags_BCAST) { return handleBeacon(msg, ici); } int epIndex = Map_EndpointsBySockaddr_indexForKey(&lladdr, &ici->peerMap); if (epIndex == -1) { return handleUnexpectedIncoming(msg, ici); } struct Peer* ep = Identity_check((struct Peer*) ici->peerMap.values[epIndex]); Message_shift(msg, -lladdr->addrLen, NULL); if (CryptoAuth_decrypt(ep->caSession, msg)) { return NULL; } PeerLink_recv(msg, ep->peerLink); return receivedPostCryptoAuth(msg, ep, ici->ic); }
static void sessionStats(Dict* args, void* vcontext, String* txid, struct Allocator* alloc) { struct Context* context = vcontext; int64_t* handleP = Dict_getInt(args, String_CONST("handle")); uint32_t handle = *handleP; struct SessionManager_Session* session = SessionManager_sessionForHandle(handle, context->sm); uint8_t* ip6 = SessionManager_getIp6(handle, context->sm); Dict* r = Dict_new(alloc); if (!session) { Dict_putString(r, String_CONST("error"), String_CONST("no such session"), alloc); Admin_sendMessage(r, txid, context->admin); return; } // both or neither Assert_true(ip6); uint8_t printedAddr[40]; AddrTools_printIp(printedAddr, ip6); Dict_putString(r, String_CONST("ip6"), String_new(printedAddr, alloc), alloc); Dict_putString(r, String_CONST("state"), String_new(CryptoAuth_stateString(session->cryptoAuthState), alloc), alloc); struct ReplayProtector* rp = CryptoAuth_getReplayProtector(session->internal); Dict_putInt(r, String_CONST("duplicates"), rp->duplicates, alloc); Dict_putInt(r, String_CONST("lostPackets"), rp->lostPackets, alloc); Dict_putInt(r, String_CONST("receivedOutOfRange"), rp->receivedOutOfRange, alloc); uint8_t* key = CryptoAuth_getHerPublicKey(session->internal); Dict_putString(r, String_CONST("publicKey"), Key_stringify(key, alloc), alloc); Dict_putInt(r, String_CONST("version"), session->version, alloc); Dict_putInt(r, String_CONST("handle"), Endian_bigEndianToHost32(session->receiveHandle_be), alloc); Dict_putInt(r, String_CONST("sendHandle"), Endian_bigEndianToHost32(session->sendHandle_be), alloc); Dict_putInt(r, String_CONST("timeOfLastIn"), session->timeOfLastIn, alloc); Dict_putInt(r, String_CONST("timeOfLastOut"), session->timeOfLastOut, alloc); Admin_sendMessage(r, txid, context->admin); return; }
static int rpcCall0(String* function, Dict* args, struct Context* ctx, struct Allocator* alloc, Dict** resultP, bool exitIfError) { ctx->currentReqAlloc = Allocator_child(alloc); ctx->currentResult = NULL; struct AdminClient_Promise* promise = AdminClient_rpcCall(function, args, ctx->client, alloc); promise->callback = rpcCallback; promise->userData = ctx; EventBase_beginLoop(ctx->base); struct AdminClient_Result* res = ctx->currentResult; Assert_true(res); if (res->err) { Log_critical(ctx->logger, "Failed to make function call [%s], error: [%s]", AdminClient_errorString(res->err), function->bytes); die(res, ctx, alloc); } String* error = Dict_getString(res->responseDict, String_CONST("error")); int ret = 0; if (error && !String_equals(error, String_CONST("none"))) { if (exitIfError) { Log_critical(ctx->logger, "Got error [%s] calling [%s]", error->bytes, function->bytes); die(res, ctx, alloc); } Log_warn(ctx->logger, "Got error [%s] calling [%s], ignoring.", error->bytes, function->bytes); ret = 1; } if (resultP) { *resultP = res->responseDict; } else { Allocator_free(ctx->currentReqAlloc); } ctx->currentReqAlloc = NULL; return ret; }
static void traceStep(struct RouteTracer_Trace* trace, struct Node* next) { struct RouteTracer_pvt* ctx = Identity_cast((struct RouteTracer_pvt*)trace->tracer); if (!next) { // can't find a next node, stalled. Timeout_setTimeout(noPeers, trace, 0, trace->tracer->eventBase, trace->pub.alloc); return; } Assert_true(LabelSplicer_routesThrough(trace->target, next->address.path)); trace->lastNodeAsked = next->address.path; struct RouterModule_Promise* rp = RouterModule_newMessage(next, 0, ctx->router, trace->pub.alloc); Dict* message = Dict_new(rp->alloc); #ifdef Version_4_COMPAT if (next->version < 5) { // The node doesn't support the new API so try running a search for // the bitwise complement of their address to get some peers. Dict_putString(message, CJDHTConstants_QUERY, CJDHTConstants_QUERY_FN, rp->alloc); String* notAddr = String_newBinary((char*)next->address.ip6.bytes, 16, rp->alloc); for (int i = 0; i < 16; i++) { notAddr->bytes[i] ^= 0xff; } Dict_putString(message, CJDHTConstants_TARGET, notAddr, rp->alloc); log(ctx->logger, trace, "Sending legacy search method because getpeers is unavailable"); } else { #endif Dict_putString(message, CJDHTConstants_QUERY, CJDHTConstants_QUERY_GP, rp->alloc); uint64_t labelForThem = LabelSplicer_unsplice(trace->target, next->address.path); labelForThem = Endian_hostToBigEndian64(labelForThem); String* target = String_newBinary((char*)&labelForThem, 8, rp->alloc); Dict_putString(message, CJDHTConstants_TARGET, target, rp->alloc); log(ctx->logger, trace, "Sending getpeers request"); #ifdef Version_4_COMPAT } #endif rp->userData = trace; rp->callback = responseCallback; RouterModule_sendMessage(rp, message); }
int InterfaceController_getPeerStats(struct InterfaceController* ifController, struct Allocator* alloc, struct InterfaceController_PeerStats** statsOut) { struct InterfaceController_pvt* ic = Identity_check((struct InterfaceController_pvt*) ifController); int count = 0; for (int i = 0; i < ic->icis->length; i++) { struct InterfaceController_Iface_pvt* ici = ArrayList_OfIfaces_get(ic->icis, i); count += ici->peerMap.count; } struct InterfaceController_PeerStats* stats = Allocator_calloc(alloc, sizeof(struct InterfaceController_PeerStats), count); int xcount = 0; for (int j = 0; j < ic->icis->length; j++) { struct InterfaceController_Iface_pvt* ici = ArrayList_OfIfaces_get(ic->icis, j); for (int i = 0; i < (int)ici->peerMap.count; i++) { struct Peer* peer = Identity_check((struct Peer*) ici->peerMap.values[i]); struct InterfaceController_PeerStats* s = &stats[xcount]; xcount++; Bits_memcpy(&s->addr, &peer->addr, sizeof(struct Address)); s->bytesOut = peer->bytesOut; s->bytesIn = peer->bytesIn; s->timeOfLastMessage = peer->timeOfLastMessage; s->state = peer->state; s->isIncomingConnection = peer->isIncomingConnection; if (peer->caSession->displayName) { s->user = String_clone(peer->caSession->displayName, alloc); } struct ReplayProtector* rp = &peer->caSession->replayProtector; s->duplicates = rp->duplicates; s->lostPackets = rp->lostPackets; s->receivedOutOfRange = rp->receivedOutOfRange; struct PeerLink_Kbps kbps; PeerLink_kbps(peer->peerLink, &kbps); s->sendKbps = kbps.sendKbps; s->recvKbps = kbps.recvKbps; } } Assert_true(xcount == count); *statsOut = stats; return count; }
// Incoming message which has passed through the cryptoauth and needs to be forwarded to the switch. static uint8_t receivedAfterCryptoAuth(struct Message* msg, struct Interface* cryptoAuthIf) { struct InterfaceController_Peer* ep = Identity_check((struct InterfaceController_Peer*) cryptoAuthIf->receiverContext); struct InterfaceController_pvt* ic = ifcontrollerForPeer(ep); ep->bytesIn += msg->length; int caState = CryptoAuth_getState(cryptoAuthIf); if (ep->state < InterfaceController_PeerState_ESTABLISHED) { // EP states track CryptoAuth states... ep->state = caState; if (caState == CryptoAuth_ESTABLISHED) { moveEndpointIfNeeded(ep, ic); } else { // prevent some kinds of nasty things which could be done with packet replay. // This is checking the message switch header and will drop it unless the label // directs it to *this* router. if (msg->length < 8 || msg->bytes[7] != 1) { Log_info(ic->logger, "DROP message because CA is not established."); return Error_NONE; } else { // When a "server" gets a new connection from a "client" the router doesn't // know about that client so if the client sends a packet to the server, the // server will be unable to handle it until the client has sent inter-router // communication to the server. Here we will ping the client so when the // server gets the ping response, it will insert the client into its table // and know its version. // prevent DoS by limiting the number of times this can be called per second // limit it to 7, this will affect innocent packets but it doesn't matter much // since this is mostly just an optimization and for keeping the tests happy. if ((ep->pingCount + 1) % 7) { sendPing(ep); } } } } else if (ep->state == InterfaceController_PeerState_UNRESPONSIVE && caState == CryptoAuth_ESTABLISHED) { ep->state = InterfaceController_PeerState_ESTABLISHED; } else { ep->timeOfLastMessage = Time_currentTimeMilliseconds(ic->eventBase); } Identity_check(ep); Assert_true(!(msg->capacity % 4)); return Interface_receiveMessage(&ep->switchIf, msg); }
static int closeInterface(struct Allocator_OnFreeJob* job) { struct InterfaceController_Peer* toClose = Identity_check((struct InterfaceController_Peer*) job->userData); struct InterfaceController_pvt* ic = ifcontrollerForPeer(toClose); // flush the peer from the table... Router_disconnectedPeer(ic->router, toClose->switchLabel); int index = Map_OfIFCPeerByExernalIf_indexForHandle(toClose->handle, &ic->peerMap); Assert_true(index >= 0); Map_OfIFCPeerByExernalIf_remove(index, &ic->peerMap); return 0; }
static struct Ducttape_MessageHeader* getDtHeader(struct Message* message, bool init) { int padding = message->padding; Assert_true(padding > Ducttape_MessageHeader_SIZE); Message_shift(message, padding); struct Ducttape_MessageHeader* dtHeader = (struct Ducttape_MessageHeader*) message->bytes; Message_shift(message, -padding); if (init) { Bits_memset(dtHeader, 0, Ducttape_MessageHeader_SIZE); Identity_set(dtHeader); } else { Identity_check(dtHeader); } return dtHeader; }
void NetPlatform_addAddress(const char* interfaceName, const uint8_t* address, int prefixLen, int addrFam, struct Log* logger, struct Except* eh) { if (addrFam == Sockaddr_AF_INET6) { addIp6Address(interfaceName, address, prefixLen, logger, eh); } else if (addrFam == Sockaddr_AF_INET) { addIp4Address(interfaceName, address, prefixLen, logger, eh); } else { Assert_true(0); } }
static Iface_DEFUN messageToAngel(struct Message* msg, struct Iface* iface) { struct NodeContext* ctx = Identity_check((struct NodeContext*) iface); if (ctx->boundAddr) { return 0; } struct Allocator* alloc = Allocator_child(ctx->alloc); Dict* config = BencMessageReader_read(msg, alloc, NULL); Dict* admin = Dict_getDict(config, String_CONST("admin")); String* bind = Dict_getString(admin, String_CONST("bind")); struct Sockaddr_storage ss; Assert_true(!Sockaddr_parse(bind->bytes, &ss)); ctx->boundAddr = Sockaddr_clone(&ss.addr, ctx->alloc); Allocator_free(alloc); EventBase_endLoop(ctx->base); return 0; }
static void onConnectionParent(struct Pipe* p, int status) { Assert_true(!status); struct Context* c = Identity_check((struct Context*) p->userData); struct Allocator* alloc = Allocator_child(c->alloc); uint8_t* bytes = Allocator_calloc(alloc, CString_strlen(MESSAGE) + 1, 1); Bits_memcpy(bytes, MESSAGE, CString_strlen(MESSAGE)); struct Message* m = Allocator_clone(alloc, (&(struct Message) { .length = CString_strlen(MESSAGE), .padding = 0, .capacity = CString_strlen(MESSAGE), .alloc = alloc, .bytes = bytes }));
static uint8_t sendTo(struct Message* msg, struct Interface* iface) { struct TestFramework_Link* link = Identity_check((struct TestFramework_Link*)iface->senderContext); Assert_true(!((uintptr_t)msg->bytes % 4) || !"alignment fault"); Assert_true(!(msg->capacity % 4) || !"length fault"); Assert_true(((int)msg->capacity >= msg->length) || !"length fault0"); struct Interface* dest; struct TestFramework* srcTf; if (&link->destIf == iface) { dest = &link->srcIf; srcTf = link->dest; } else if (&link->srcIf == iface) { dest = &link->destIf; srcTf = link->src; } else { Assert_true(false); } printf("Transferring message to [%p] - message length [%d]\n", (void*)dest, msg->length); // Store the original message and a copy of the original so they can be compared later. srcTf->lastMsgBackup = Message_clone(msg, srcTf->alloc); srcTf->lastMsg = msg; if (msg->alloc) { // If it's a message which was buffered inside of CryptoAuth then it will be freed // so by adopting the allocator we can hold it in memory. Allocator_adopt(srcTf->alloc, msg->alloc); } // Copy the original and send that to the other end. struct Message* sendMsg = Message_clone(msg, dest->allocator); return dest->receiveMessage(sendMsg, dest); }
static uint8_t sendMessage(struct Message* message, struct Interface* interface) { struct CryptoAuth_Wrapper* wrapper = Identity_cast((struct CryptoAuth_Wrapper*) interface->senderContext); // If there has been no incoming traffic for a while, reset the connection to state 0. // This will prevent "connection in bad state" situations from lasting forever. uint64_t nowSecs = Time_currentTimeSeconds(wrapper->context->eventBase); if (nowSecs - wrapper->timeOfLastPacket > wrapper->context->pub.resetAfterInactivitySeconds) { Log_debug(wrapper->context->logger, "No traffic in [%d] seconds, resetting connection.", (int) (nowSecs - wrapper->timeOfLastPacket)); wrapper->timeOfLastPacket = nowSecs; CryptoAuth_reset(interface); return encryptHandshake(message, wrapper); } #ifdef Log_DEBUG Assert_true(!((uintptr_t)message->bytes % 4) || !"alignment fault"); #endif // nextNonce 0: sending hello, we are initiating connection. // nextNonce 1: sending another hello, nothing received yet. // nextNonce 2: sending key, hello received. // nextNonce 3: sending key again, no data packet recieved yet. // nextNonce >3: handshake complete // // if it's a blind handshake, every message will be empty and nextNonce will remain // zero until the first message is received back. if (wrapper->nextNonce < 5) { if (wrapper->nextNonce < 4) { return encryptHandshake(message, wrapper); } else { Log_debug(wrapper->context->logger, "@%p Doing final step to send message. nonce=4\n", (void*) wrapper); uint8_t secret[32]; getSharedSecret(secret, wrapper->secret, wrapper->tempKey, NULL, wrapper->context->logger); Bits_memcpyConst(wrapper->secret, secret, 32); } } return encryptMessage(message, wrapper); }
struct AddrInterface* TUNTools_setupUDP(struct EventBase* base, struct Sockaddr* bindAddr, struct Allocator* allocator, struct Log* logger) { // Mac OSX and BSD do not set up their TUN devices synchronously. // We'll just keep on trying until this works. struct AddrInterface* udp = NULL; for (int i = 0; i < 20; i++) { if ((udp = setupUDP2(base, bindAddr, allocator, logger))) { break; } } Assert_true(udp); return udp; }
/** * Encrypt and authenticate. * Shifts the message by 16 bytes. * * @param nonce a 24 byte number, may be random, cannot repeat. * @param msg a message to encipher and authenticate. * @param secret a shared secret. */ static inline void encryptRndNonce(uint8_t nonce[24], struct Message* msg, uint8_t secret[32]) { Assert_true(msg->padding >= 32); uint8_t* startAt = msg->bytes - 32; // This function trashes 16 bytes of the padding so we will put it back uint8_t paddingSpace[16]; Bits_memcpyConst(paddingSpace, startAt, 16); Bits_memset(startAt, 0, 32); crypto_box_curve25519xsalsa20poly1305_afternm( startAt, startAt, msg->length + 32, nonce, secret); Bits_memcpyConst(startAt, paddingSpace, 16); Message_shift(msg, 16, NULL); }
/** * Send a search request to the next node in this search. * This is called whenever a response comes in or after the global mean response time passes. */ static void searchStep(struct SearchRunner_Search* search) { struct SearchRunner_pvt* ctx = Identity_check((struct SearchRunner_pvt*)search->runner); struct Node_Two* node; struct SearchStore_Node* nextSearchNode; for (;;) { nextSearchNode = SearchStore_getNextNode(search->search); // If the number of requests sent has exceeded the max search requests, let's stop there. if (search->totalRequests >= MAX_REQUESTS_PER_SEARCH || nextSearchNode == NULL) { if (search->pub.callback) { search->pub.callback(&search->pub, 0, NULL, NULL); } Allocator_free(search->pub.alloc); return; } node = NodeStore_getBest(&nextSearchNode->address, ctx->nodeStore); if (!node) { continue; } if (node == ctx->nodeStore->selfNode) { continue; } if (Bits_memcmp(node->address.ip6.bytes, nextSearchNode->address.ip6.bytes, 16)) { continue; } break; } Assert_true(node != ctx->nodeStore->selfNode); Bits_memcpyConst(&search->lastNodeAsked, &node->address, sizeof(struct Address)); struct RouterModule_Promise* rp = RouterModule_newMessage(&node->address, 0, ctx->router, search->pub.alloc); Dict* message = Dict_new(rp->alloc); Dict_putString(message, CJDHTConstants_QUERY, CJDHTConstants_QUERY_FN, rp->alloc); Dict_putString(message, CJDHTConstants_TARGET, search->targetStr, rp->alloc); rp->userData = search; rp->callback = searchCallback; RouterModule_sendMessage(rp, message); search->totalRequests++; }
/** * Handle an incoming control message from a switch. * * @param context the ducttape context. * @param message the control message, this should be alligned on the beginning of the content, * that is to say, after the end of the switch header. * @param switchHeader the header. * @param switchIf the interface which leads to the switch. * @param isFormV8 true if the control message is in the form specified by protocol version 8+ */ static Iface_DEFUN incomingFromCore(struct Message* msg, struct Iface* coreIf) { struct ControlHandler_pvt* ch = Identity_check((struct ControlHandler_pvt*) coreIf); struct RouteHeader routeHdr; Message_pop(msg, &routeHdr, RouteHeader_SIZE, NULL); uint8_t labelStr[20]; uint64_t label = Endian_bigEndianToHost64(routeHdr.sh.label_be); AddrTools_printPath(labelStr, label); // happens in benchmark // Log_debug(ch->log, "ctrl packet from [%s]", labelStr); if (msg->length < 4 + Control_Header_SIZE) { Log_info(ch->log, "DROP runt ctrl packet from [%s]", labelStr); return NULL; } Assert_true(routeHdr.flags & RouteHeader_flags_CTRLMSG); if (Checksum_engine(msg->bytes, msg->length)) { Log_info(ch->log, "DROP ctrl packet from [%s] with invalid checksum", labelStr); return NULL; } struct Control* ctrl = (struct Control*) msg->bytes; if (ctrl->header.type_be == Control_ERROR_be) { return handleError(msg, ch, label, labelStr); } else if (ctrl->header.type_be == Control_KEYPING_be || ctrl->header.type_be == Control_PING_be) { return handlePing(msg, ch, label, labelStr, ctrl->header.type_be); } else if (ctrl->header.type_be == Control_KEYPONG_be || ctrl->header.type_be == Control_PONG_be) { Log_debug(ch->log, "got switch pong from [%s]", labelStr); Message_push(msg, &routeHdr, RouteHeader_SIZE, NULL); return Iface_next(&ch->pub.switchPingerIf, msg); } Log_info(ch->log, "DROP control packet of unknown type from [%s], type [%d]", labelStr, Endian_bigEndianToHost16(ctrl->header.type_be)); return NULL; }
/** * Handle an incoming control message from a switch. * * @param context the ducttape context. * @param message the control message, this should be alligned on the beginning of the content, * that is to say, after the end of the switch header. * @param switchHeader the header. * @param switchIf the interface which leads to the switch. * @param isFormV8 true if the control message is in the form specified by protocol version 8+ */ static Iface_DEFUN incomingFromCore(struct Message* msg, struct Iface* coreIf) { struct ControlHandler_pvt* ch = Identity_check((struct ControlHandler_pvt*) coreIf); struct SwitchHeader switchHeader; Message_pop(msg, &switchHeader, SwitchHeader_SIZE, NULL); uint8_t labelStr[20]; uint64_t label = Endian_bigEndianToHost64(switchHeader.label_be); AddrTools_printPath(labelStr, label); Log_debug(ch->log, "ctrl packet from [%s]", labelStr); if (msg->length < 4 + Control_Header_SIZE) { Log_info(ch->log, "DROP runt ctrl packet from [%s]", labelStr); return NULL; } Assert_true(Message_pop32(msg, NULL) == 0xffffffff); if (Checksum_engine(msg->bytes, msg->length)) { Log_info(ch->log, "DROP ctrl packet from [%s] with invalid checksum", labelStr); return NULL; } struct Control* ctrl = (struct Control*) msg->bytes; if (ctrl->header.type_be == Control_ERROR_be) { return handleError(msg, ch, label, labelStr); } else if (ctrl->header.type_be == Control_KEYPING_be || ctrl->header.type_be == Control_PING_be) { return handlePing(msg, ch, label, labelStr, ctrl->header.type_be); } else if (ctrl->header.type_be == Control_KEYPONG_be || ctrl->header.type_be == Control_PONG_be) { Log_debug(ch->log, "got switch pong from [%s]", labelStr); // Shift back over the header Message_shift(msg, 4 + SwitchHeader_SIZE, NULL); return Iface_next(&ch->pub.switchPingerIf, msg); } Log_info(ch->log, "DROP control packet of unknown type from [%s], type [%d]", labelStr, Endian_bigEndianToHost16(ctrl->header.type_be)); return NULL; }
static Iface_DEFUN searchReq(struct Message* msg, struct Pathfinder_pvt* pf) { uint8_t addr[16]; Message_pop(msg, addr, 16, NULL); Assert_true(!msg->length); uint8_t printedAddr[40]; AddrTools_printIp(printedAddr, addr); Log_debug(pf->log, "Search req [%s]", printedAddr); struct Node_Two* node = NodeStore_nodeForAddr(pf->nodeStore, addr); if (node) { onBestPathChange(pf, node); } else { SearchRunner_search(addr, 20, 3, pf->searchRunner, pf->alloc); } return NULL; }
static void done(struct Context* ctx) { uint64_t endTimes = Time_hrtime(); uint64_t time = (endTimes - ctx->startTime) / 1000000; // same as items / (time / 1024) (converting time to seconds) uint64_t kbps = (ctx->items * 1024) / time; Log_info(ctx->log, " "); Log_info(ctx->log, "---------------------------------------------------------------"); Log_info(ctx->log, "Benchmark %s in %dms. %d %s per second", ctx->benchName, (int)time, (int)kbps, ctx->itemName); Log_info(ctx->log, "---------------------------------------------------------------"); Log_info(ctx->log, " "); Assert_true(ctx->benchName); ctx->benchName = NULL; }
int main() { struct Allocator* alloc = MallocAllocator_new(1024); struct Random* rand = Random_new(alloc, NULL, NULL); FILE* tmp = tmpfile(); uint8_t buffer1[2048]; size_t checkSize; Random_bytes(rand, buffer1, 2048); checkSize = fwrite(buffer1, 1, 2048, tmp); if (checkSize != 2048) { return 1; } uint8_t buffer2[1024]; rewind(tmp); struct Reader* r = FileReader_new(tmp, alloc); Reader_read(r, buffer2, 128); Reader_skip(r, 128); Reader_read(r, buffer2+128, 128); Reader_skip(r, 512); Reader_read(r, buffer2+128+128, 256); Reader_skip(r, 300); Reader_read(r, buffer2+128+128+256, 128); Assert_true(r->bytesRead == 128+128+128+512+256+300+128); uint8_t* ptr1 = buffer1; uint8_t* ptr2 = buffer2; #define SKIP(x) ptr1 += x #define CMP(x) Assert_true(!Bits_memcmp(ptr1, ptr2, x)); ptr1 += x; ptr2 += x CMP(128); SKIP(128); CMP(128); SKIP(512); CMP(256); SKIP(300); CMP(128); Allocator_free(alloc); return 0; }
static struct Address* getBest(struct RumorMill_pvt* rm) { if (rm->pub.count == 0) { return NULL; } struct Address* best = NULL; int howBadIsTheBest = -1; for (int i = 0; i < rm->pub.count; i++) { int howBad = getBadness(&rm->pub.addresses[i], rm->selfAddr); if (howBad < howBadIsTheBest || !best) { howBadIsTheBest = howBad; best = &rm->pub.addresses[i]; } } Assert_true(best); return best; }
// only in parent static void inFromChildSkipMmsg(struct Admin* admin) { Assert_true(admin->messageHeader.length > 0); uint8_t buffer[MAX_MESSAGE_SIZE]; uint32_t have = 0; int amount = inFromChildFillBuffer(admin, buffer, MAX_MESSAGE_SIZE, &have, admin->messageHeader.length); if (amount < 0) { return; } admin->messageHeader.length -= amount; if (0 == admin->messageHeader.length) { admin->haveMessageHeaderLen = 0; } }
static inline uint8_t encryptMessage(struct Message* message, struct CryptoAuth_Wrapper* wrapper) { Assert_true(message->padding >= 36 || !"not enough padding"); encrypt(wrapper->nextNonce, message, wrapper->sharedSecret, wrapper->isInitiator); Message_shift(message, 4, NULL); union Headers_CryptoAuth* header = (union Headers_CryptoAuth*) message->bytes; header->nonce = Endian_hostToBigEndian32(wrapper->nextNonce); wrapper->nextNonce++; return wrapper->wrappedInterface->sendMessage(message, wrapper->wrappedInterface); }
static void onReply(Dict* msg, struct Address* src, struct MsgCore_Promise* prom) { struct ReachabilityCollector_pvt* rcp = Identity_check((struct ReachabilityCollector_pvt*) prom->userData); Assert_true(prom == rcp->msgOnWire); if (!src) { onReplyTimeout(prom); mkNextRequest(rcp); return; } struct Address_List* results = ReplySerializer_parse(src, msg, rcp->log, false, prom->alloc); uint64_t path = 1; struct PeerInfo* pi = NULL; for (int j = 0; j < rcp->piList->length; j++) { struct PeerInfo* pi0 = ArrayList_OfPeerInfo_get(rcp->piList, j); if (Address_isSameIp(&pi0->addr, src)) { pi = pi0; break; } } if (!pi) { Log_debug(rcp->log, "Got message from peer which is gone from list"); return; } for (int i = 0; i < results->length; i++) { path = results->elems[i].path; if (Bits_memcmp(results->elems[i].ip6.bytes, rcp->myAddr->ip6.bytes, 16)) { continue; } if (pi->pathThemToUs != path) { Log_debug(rcp->log, "Found back-route for [%s]", Address_toString(src, prom->alloc)->bytes); if (rcp->pub.onChange) { rcp->pub.onChange( &rcp->pub, src->ip6.bytes, path, src->path, 0, 0xffff, 0xffff, 0xffff); } } pi->pathThemToUs = path; pi->querying = false; return; } pi->pathToCheck = (results->length < 8) ? 1 : path; mkNextRequest(rcp); }