int proto_expectation_add(struct proto_expectation *e, struct conntrack_session *session, unsigned int expiry, ptime now) { if (!e || !e->tail || !e->tail->proto) { pomlog(POMLOG_ERR "Cannot add expectation as it's incomplete"); return POM_ERR; } e->expiry = timer_alloc(e, proto_expectation_expiry); if (!e->expiry) return POM_ERR; if (timer_queue_now(e->expiry, expiry, now) != POM_OK) return POM_ERR; conntrack_session_refcount_inc(session); e->session = session; struct proto *proto = e->tail->proto; pom_rwlock_wlock(&proto->expectation_lock); e->next = proto->expectations; if (e->next) e->next->prev = e; proto->expectations = e; pom_rwlock_unlock(&proto->expectation_lock); registry_perf_inc(e->proto->perf_expt_pending, 1); return POM_OK; }
int proto_expectation_add_and_cleanup(struct proto_expectation *e, unsigned int expiry, ptime now) { if (e->flags & PROTO_EXPECTATION_FLAG_QUEUED) return POM_ERR; if (proto_expectation_add(e) != POM_OK) return POM_ERR; e->expiry = timer_alloc(e, proto_expectation_timeout); if (!e->expiry) return POM_ERR; if (timer_queue_now(e->expiry, expiry, now) != POM_OK) return POM_ERR; return POM_OK; }
int conntrack_delayed_cleanup(struct conntrack_entry *ce, unsigned int delay, ptime now) { if (!delay) { if (ce->cleanup_timer && ce->cleanup_timer != (void*)-1) { timer_dequeue(ce->cleanup_timer->timer); timer_cleanup(ce->cleanup_timer->timer); free(ce->cleanup_timer); ce->cleanup_timer = NULL; } return POM_OK; } if (ce->cleanup_timer == (void *) -1) { debug_conntrack("Not queuing timer for conntrack %p as it is currently being cleaned up", ce); return POM_OK; } if (!ce->cleanup_timer) { ce->cleanup_timer = malloc(sizeof(struct conntrack_timer)); if (!ce->cleanup_timer) { pom_oom(sizeof(struct conntrack_timer)); return POM_ERR; } ce->cleanup_timer->timer = timer_alloc(ce->cleanup_timer, conntrack_timed_cleanup); if (!ce->cleanup_timer->timer) { free(ce->cleanup_timer); ce->cleanup_timer = NULL; return POM_ERR; } ce->cleanup_timer->ce = ce; ce->cleanup_timer->proto = ce->proto; ce->cleanup_timer->hash = ce->hash; } timer_queue_now(ce->cleanup_timer->timer, delay, now); return POM_OK; }
int timer_queue(struct timer *t, unsigned int expiry) { return timer_queue_now(t, expiry, core_get_clock_last()); }
static int analyzer_docsis_pkt_process(void *obj, struct packet *p, struct proto_process_stack *stack, unsigned int stack_index) { struct analyzer *analyzer = obj; struct analyzer_docsis_priv *priv = analyzer->priv; struct proto_process_stack *s = &stack[stack_index]; uint8_t *type = PTYPE_UINT8_GETVAL(s->pkt_info->fields_value[proto_docsis_mgmt_field_type]); char *mac_dst = PTYPE_MAC_GETADDR(s->pkt_info->fields_value[proto_docsis_mgmt_field_dst]); // FIXME : improve this filtering at the source // Filter some useless messages we don't care about if (*type == MMT_UCD2 || *type == MMT_UCD3 || *type == MMT_MDD) return POM_OK; if (*type != MMT_RNG_RSP) { pomlog(POMLOG_DEBUG "Unhandled DOCSIS MGMT message type %u for destination mac %02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX", *type, mac_dst[0], mac_dst[1], mac_dst[2], mac_dst[3], mac_dst[4], mac_dst[5]); return POM_OK; } // Use the last bits for the modem ID uint16_t id = ntohs(*(uint16_t*) (mac_dst + 4)) & ANALYZER_DOCSIS_CM_MASK; pom_mutex_lock(&priv->lock); struct analyzer_docsis_cm *cm; for (cm = priv->cms[id]; cm; cm = cm->next) { if (!memcmp(cm->mac, mac_dst, sizeof(cm->mac))) break; } if (!cm) { // Cable modem not found ! cm = malloc(sizeof(struct analyzer_docsis_cm)); if (!cm) { pom_mutex_unlock(&priv->lock); pom_oom(sizeof(struct analyzer_docsis_cm)); return POM_ERR; } memset(cm, 0, sizeof(struct analyzer_docsis_cm)); cm->t = timer_alloc(cm, analyzer_docsis_cm_timeout); if (!cm->t) { pom_mutex_unlock(&priv->lock); free(cm); return POM_ERR; } cm->analyzer = analyzer; memcpy(cm->mac, mac_dst, sizeof(cm->mac)); cm->t4_multiplier = 1; cm->next = priv->cms[id]; if (cm->next) cm->next->prev = cm; priv->cms[id] = cm; // Announce the new CM if (event_has_listener(priv->evt_cm_new)) { struct event *evt = event_alloc(priv->evt_cm_new); if (!evt) { pom_mutex_unlock(&priv->lock); return POM_ERR; } struct data *evt_data = event_get_data(evt); PTYPE_MAC_SETADDR(evt_data[analyzer_docsis_cm_new_mac].value, cm->mac); data_set(evt_data[analyzer_docsis_cm_new_mac]); PTYPE_STRING_SETVAL(evt_data[analyzer_docsis_cm_new_input].value, p->input->name); data_set(evt_data[analyzer_docsis_cm_new_input]); if (event_process(evt, stack, stack_index, p->ts) != POM_OK) { pom_mutex_unlock(&priv->lock); return POM_ERR; } } } switch (*type) { case MMT_RNG_RSP: analyzer_docsis_pkt_parse_rng_rsp(priv, cm, p, stack, stack_index); break; // FIXME If ranging_status is 0 and we receive another msg, probably it's actually registered // and we need to call analyzer_docsis_reg_status_update(); } timer_queue_now(cm->t, T4_TIMEOUT * cm->t4_multiplier, p->ts); pom_mutex_unlock(&priv->lock); return POM_OK; }
int conntrack_timer_queue(struct conntrack_timer *t, unsigned int expiry, ptime now) { return timer_queue_now(t->timer, expiry, now); }