diff --git a/dynmem.c b/dynmem.c index eb6ba5d..dbbb7c6 100644 --- a/dynmem.c +++ b/dynmem.c @@ -3,20 +3,28 @@ #include "utils.h" #if !defined(ETHLIB_MEMORY_POOL_ATTRIBUTES) - static uint8_t sDynMemPool[ETHLIB_MEMORY_POOL_TOTAL_SIZE]; +static uint8_t sDynMemPool[ETHLIB_MEMORY_POOL_TOTAL_SIZE]; #else - static uint8_t sDynMemPool[ETHLIB_MEMORY_POOL_TOTAL_SIZE] __attribute__((ETHLIB_MEMORY_POOL_ATTRIBUTES)); +static uint8_t sDynMemPool[ETHLIB_MEMORY_POOL_TOTAL_SIZE] __attribute__((ETHLIB_MEMORY_POOL_ATTRIBUTES)); #endif +static ETHLIB_OS_MTX_TYPE dynmem_mtx; + void dynmem_init() { + ETHLIB_OS_MTX_CREATE(&dynmem_mtx); E.mp = mp_init(sDynMemPool, ETHLIB_MEMORY_POOL_TOTAL_SIZE); ASSERT_NULL(E.mp); } -void * dynmem_alloc_(uint32_t size) { - return mp_alloc(E.mp, size); +void *dynmem_alloc_(uint32_t size) { + ETHLIB_OS_MTX_LOCK(&dynmem_mtx); + void * p = mp_alloc(E.mp, size); + ETHLIB_OS_MTX_UNLOCK(&dynmem_mtx); + return p; } -void dynmem_free_(const void * ptr) { - mp_free(E.mp, (const uint8_t *)ptr); +void dynmem_free_(const void *ptr) { + ETHLIB_OS_MTX_LOCK(&dynmem_mtx); + mp_free(E.mp, (const uint8_t *) ptr); + ETHLIB_OS_MTX_UNLOCK(&dynmem_mtx); } diff --git a/eth_interface.c b/eth_interface.c index 17827de..8298ad2 100644 --- a/eth_interface.c +++ b/eth_interface.c @@ -60,7 +60,7 @@ EthInterface *ethintf_new(EthIODef *io) { ETHLIB_OS_THREAD_DEFINE(task_ethintf, osPriorityHigh, 512, ethIntf); ETHLIB_OS_THREAD_CREATE(task_ethintf, ethIntf); - ethIntf->ipra = ipra_new(); + ethIntf->ipra = ipra_new(ethIntf); ethIntf->capabilities = 0; diff --git a/packet_sieve.c b/packet_sieve.c index b8d2f18..9fcbf51 100644 --- a/packet_sieve.c +++ b/packet_sieve.c @@ -25,6 +25,19 @@ PcktSieve* packsieve_new(EthInterface *intf) { } void packsieve_input(PcktSieve *sieve, const RawPckt *rawPckt) { + /* First we acquire the packet class and see if we know the way how of its processing at all. + * + * 1.: Get packet descriptor, decide, if we can process this kind of packet or not. + * 2.: Fill in common header fields, and chain in the header if possible. + * 3.: Parse the packet header (extract fields etc.). + * 4.: Fetch the contained packet class. + * 5.: Skip the header if found, make the respective pointer to point on the payload. + * 6.: Make the just processed contained packet the container for the processing of the next iteration. + * + * Next, we search the sieve tree if there was such a layer. + * + */ + // extract fields uint8_t *data = rawPckt->payload; uint32_t size = rawPckt->size; @@ -38,7 +51,7 @@ void packsieve_input(PcktSieve *sieve, const RawPckt *rawPckt) { int procRet; do { - // get packet descriptor + // [1.] get packet descriptor PcktClassDesc *cdesc = packreg_get_by_class(E.pcktReg, ownClass, containerClass); if (cdesc == NULL) { break; @@ -55,48 +68,54 @@ void packsieve_input(PcktSieve *sieve, const RawPckt *rawPckt) { cdesc->cacheSize = hdrSize; // retain cache size } + // make header to point on cache area header = (PcktHeaderElement*) cdesc->cacheArea; + // [2.] write header fields memset(header, 0, hdrSize); header->props.ownPacketClass = ownClass; header->props.propSize = cdesc->propertySize; header->prev = lastHeader; - if (lastHeader) { + if (lastHeader) { // if a previous header exists, then fill-in the next field lastHeader->next = header; } - if (outermostHeader == NULL) { - outermostHeader = header; + if (outermostHeader == NULL) { // if no previous headers are chained, then it's the first one... + outermostHeader = header; // and make it the outermost header } - // call parsing function + // [3.] call parsing function PcktProcFnPassbackData pb; procRet = cdesc->procFun(data + offset, size - offset, header, sieve->intf, &pb); - switch (procRet) { - case PROC_FN_RET_REPRST: + switch (procRet) { // execute further action based on the return value of the parsing function + case PROC_FN_RET_REPRST: // replace packet and restart processing dynmem_free(data); // release previous packet data - data = pb.p; // store new packet data + data = pb.p; // store new packet data passed back in pb size = pb.u; mrd = pb.b; // NO BREAK! - case PROC_FN_RET_ABORT: + case PROC_FN_RET_ABORT: // abort packet processing goto header_release; // GOTO :D! break; - case PROC_FN_RET_OK: + case PROC_FN_RET_OK: // no extra processing steps default: break; } + // [4.] get the contained packet class uint16_t containedClass = header->props.containedPacketClass; if (containedClass != 0) { containerClass = ownClass; //dynmem_free(props); } + + // [5.] adjust offsets based on the just processed header (skip header) offset += header->props.headerSize; header->props.accumulatedOffset = offset; header->props.bytesToEnd = size - header->props.accumulatedOffset; header->props.hdrInsFn = cdesc->hdrInsFn; + // [6.] advance deeper in the packet ownClass = containedClass; lastHeader = header; } while ((ownClass != 0) && lastHeader->props.validityOK); @@ -119,18 +138,19 @@ void packsieve_input(PcktSieve *sieve, const RawPckt *rawPckt) { packet.time_ns = rawPckt->ext.rx.time_ns; // lookup headers in the sieve - PcktHeaderElement *headerIter = outermostHeader; + PcktHeaderElement *headerIter = outermostHeader; // place iterator on the outermost header PcktSieveLayer *layer = &sieve->layer0; // innermost matched sieve layer bool found = true; // first structure is always an Ethernet-frame while (found && headerIter) { - PcktSieveLayer *nodeIter = layer->nodes; - found = false; - while (nodeIter && !found) { - found |= nodeIter->matchAny || nodeIter->filtFn(&nodeIter->filtCond, &headerIter->props, &headerIter->next->props, sieve->intf); // specific or general match - if (found) { + PcktSieveLayer *nodeIter = layer->nodes; // select the frames nodes + found = false; // assume that the layer is not found + // iteration on SUBnodes! (so on the first layer...) + while (nodeIter && !found) { // look for a matching layer until it's found, or until we have exhausted the nodes + found |= nodeIter->matchAny || nodeIter->filtFn(&nodeIter->filtCond, &headerIter->props, &headerIter->next->props, sieve->intf); // specific or general match based on current and next header + if (found) { // if layer is found... layer = nodeIter; // advance in the sieve tree - PcktHeaderElement *containedHeader = headerIter; - if (headerIter->next != NULL) { + PcktHeaderElement *containedHeader = headerIter; // select header corresponding to current layer + if (headerIter->next != NULL) { // make contained header to point on contained packet header if exists containedHeader = containedHeader->next; // advance on headers } if (layer->cbFn != NULL) { // if defined, invoke layer callback function diff --git a/prefab/conn_blocks/ipv4/ip_assembler.c b/prefab/conn_blocks/ipv4/ip_assembler.c index da1993d..62f9385 100644 --- a/prefab/conn_blocks/ipv4/ip_assembler.c +++ b/prefab/conn_blocks/ipv4/ip_assembler.c @@ -5,9 +5,10 @@ #include "../../../dynmem.h" #include "../../../global_state.h" -IPv4Assembler *ipra_new() { +IPv4Assembler *ipra_new(EthInterface * intf) { IPv4Assembler *ipra = (IPv4Assembler *) dynmem_alloc(sizeof(IPv4Assembler)); ipra->chains = NULL; + ipra->intf = intf; return ipra; } @@ -186,8 +187,8 @@ bool ipra_try_reassemble(IPv4Assembler *ipra, uint16_t id, uint8_t **payload, ui // release chain ipra_remove_chain(ipra, id); - insert_ethernet_header(p, pcktHdrLe->prev, NULL); - insert_ipv4_header(p + ETH_ETHERNET_HEADER_SIZE, pcktHdrLe, NULL); + insert_ethernet_header(p, pcktHdrLe->prev, ipra->intf); + insert_ipv4_header(p + ETH_ETHERNET_HEADER_SIZE, pcktHdrLe, ipra->intf); return true; } diff --git a/prefab/conn_blocks/ipv4/ip_assembler.h b/prefab/conn_blocks/ipv4/ip_assembler.h index 8f49965..0778e35 100644 --- a/prefab/conn_blocks/ipv4/ip_assembler.h +++ b/prefab/conn_blocks/ipv4/ip_assembler.h @@ -25,13 +25,14 @@ typedef struct FragChainDesc_ { typedef struct { FragChainDesc * chains; ///< Linked list of fragment chains + struct EthInterface_ * intf; ///< Interface instantiated this reassembler } IPv4Assembler; /** * Create new IPv4 packet reassembler. * @return pointer to newly allocated assembler */ -IPv4Assembler * ipra_new(); +IPv4Assembler * ipra_new(struct EthInterface_ * intf); /** * Input packet packet fragment. @@ -42,7 +43,7 @@ void ipra_input(IPv4Assembler * ipra, const IPv4Props * ipProps, const uint8_t * /** - * Try to reassembly packet. + * Attempt to reassemble a packet. * @param ipra pointer to IPv4 reassembly object * @param id packet sequence identification * @param payload pointer to uint8_t* pointer; filled only on successful reassembly diff --git a/timer.c b/timer.c index 5caef61..3daf79c 100644 --- a/timer.c +++ b/timer.c @@ -7,8 +7,6 @@ #include "utils.h" #include -// FIXME nagyon bugos vagyok! Help me! :) - int64_t time_to_us(const TimePoint *t) { return (int64_t)t->s * 1000000 + (int64_t)t->us; } @@ -65,29 +63,30 @@ static void timer_update_nearest_alarm(Timer *tmr) { return; } - int64_t t_c_us = time_to_us(&tmr->time); - int64_t min_delta_t_us = 0; + int64_t t_c_us = time_to_us(&tmr->time); // current time in microseconds + int64_t min_delta_t_us = 0; // minimal time difference - AlarmAssignment *nearest = NULL; + AlarmAssignment *nearest = NULL; // nearest alarm for (uint32_t i = 0; i < tmr->maxSched; i++) { - int64_t t_i_us = time_to_us(&(tmr->alarms[i].time)); - if ((nearest == NULL) && (tmr->alarms[i].id != 0)) { - nearest = tmr->alarms + i; + AlarmAssignment * iter = tmr->alarms + i; + int64_t t_i_us = time_to_us(&(iter->time)); + if ((nearest == NULL) && (iter->id != 0)) { // if it's the first one + nearest = iter; min_delta_t_us = t_i_us - t_c_us; - } else { - int64_t delta_t_us = t_i_us - t_c_us; + } else { // if it's not the first one + int64_t delta_t_us = t_i_us - t_c_us; // calculate time difference if (delta_t_us < min_delta_t_us) { - min_delta_t_us = delta_t_us; - nearest = tmr->alarms + i; + min_delta_t_us = delta_t_us; // replace minimum + nearest = iter; } } } - tmr->nextAlarm = nearest; + tmr->nextAlarm = nearest; // replace next alarm } uint32_t timer_sched(Timer *tmr, const TimePoint *t, TimerAlarmCb cb, AlarmUserData params) { - if (tmr->nSched == tmr->maxSched) { // if cannot schedule more alarm + if (tmr->nSched == tmr->maxSched) { // if no more alarm can be scheduled return TIMER_SCHED_FAILED; } @@ -108,7 +107,7 @@ uint32_t timer_sched(Timer *tmr, const TimePoint *t, TimerAlarmCb cb, AlarmUserD // replace nearest if needed if (tmr->nSched > 1) { timer_update_nearest_alarm(tmr); - } else { + } else { // this is merely for optimization tmr->nextAlarm = slot; } @@ -158,7 +157,7 @@ void timer_tick(Timer *tmr, int64_t us) { /*t_us += us; time_from_us(&tmr->time, t_us);*/ - int64_t t_us = timer_get_time_us(tmr); + int64_t t_us = timer_get_time_us(tmr); // convert time to microseconds if ((tmr->nSched > 0) && (tmr->nextAlarm != NULL)) { int64_t t_alarm = time_to_us(&(tmr->nextAlarm->time));