/** * * Remove expectation and return next one * * \param ipp an IPPair * \param pexp pointer to previous Expectation * \param exp pointer to Expectation to remove * \param lexp pointer to head of Expectation ist * \return expectation */ static Expectation * RemoveExpectationAndGetNext(IPPair *ipp, Expectation *pexp, Expectation *exp, Expectation *lexp) { /* we remove the object so we get ref count down by 1 to remove reference * hold by the expectation */ (void) IPPairDecrUsecnt(ipp); SC_ATOMIC_SUB(expectation_count, 1); if (pexp == NULL) { IPPairSetStorageById(ipp, g_expectation_id, lexp); } else { pexp->next = lexp; } if (exp->data) { ExpectationData *expdata = (ExpectationData *)exp->data; if (expdata->DFree) { expdata->DFree(exp->data); } else { SCFree(exp->data); } } SCFree(exp); return lexp; }
static void IPPairBitRemove(IPPair *h, uint16_t idx) { XBit *fb = IPPairBitGet(h, idx); if (fb == NULL) return; GenericVar *gv = IPPairGetStorageById(h, ippair_bit_id); if (gv) { GenericVarRemove(&gv, (GenericVar *)fb); IPPairSetStorageById(h, ippair_bit_id, gv); } }
/** * Create an entry in expectation list * * Create a expectation from an existing Flow. Currently, only Flow between * the two original IP addresses are supported. * * \param f a pointer to the original Flow * \param direction the direction of the data in the expectation flow * \param src source port of the expected flow, use 0 for any * \param dst destination port of the expected flow, use 0 for any * \param alproto the protocol that need to be set on the expected flow * \param data pointer to data that will be attached to the expected flow * * \return -1 if error * \return 0 if success */ int AppLayerExpectationCreate(Flow *f, int direction, Port src, Port dst, AppProto alproto, void *data) { Expectation *iexp = NULL; IPPair *ipp; Address ip_src, ip_dst; Expectation *exp = SCCalloc(1, sizeof(*exp)); if (exp == NULL) return -1; exp->sp = src; exp->dp = dst; exp->alproto = alproto; exp->ts = f->lastts; exp->data = data; exp->direction = direction; if (GetFlowAddresses(f, &ip_src, &ip_dst) == -1) goto error; ipp = IPPairGetIPPairFromHash(&ip_src, &ip_dst); if (ipp == NULL) goto error; iexp = IPPairGetStorageById(ipp, g_expectation_id); exp->next = iexp; IPPairSetStorageById(ipp, g_expectation_id, exp); SC_ATOMIC_ADD(expectation_count, 1); /* As we are creating the expectation, we release lock on IPPair without * setting the ref count to 0. This way the IPPair will be kept till * cleanup */ IPPairUnlock(ipp); return 0; error: SCFree(exp); return -1; }
/* add a flowbit to the flow */ static void IPPairBitAdd(IPPair *h, uint16_t idx, uint32_t expire) { XBit *fb = IPPairBitGet(h, idx); if (fb == NULL) { fb = SCMalloc(sizeof(XBit)); if (unlikely(fb == NULL)) return; fb->type = DETECT_XBITS; fb->idx = idx; fb->next = NULL; fb->expire = expire; GenericVar *gv = IPPairGetStorageById(h, ippair_bit_id); GenericVarAppend(&gv, (GenericVar *)fb); IPPairSetStorageById(h, ippair_bit_id, gv); // bit already set, lets update it's timer } else { fb->expire = expire; } }