/** * Locate the modified parameter structure for a parameter, if it exists. * * @param param The parameter being searched. * @return The structure holding the modified value, or * NULL if the parameter has not been modified. */ static struct param_wbuf_s * param_find_changed(param_t param) { struct param_wbuf_s *s = NULL; param_assert_locked(); if (param_values != NULL) { #if 0 /* utarray_find requires bsearch, not available */ struct param_wbuf_s key; key.param = param; s = utarray_find(param_values, &key, param_compare_values); #else while ((s = (struct param_wbuf_s *)utarray_next(param_values, s)) != NULL) { if (s->param == param) { break; } } #endif } return s; }
/** * Process upstream p2p bandwidth limits. * * @param[in] sess Session. * @param[in] packet_len Packet length. * @param[in] iph IP header. * @param[in] flow_dir Flow direction. * @return Zero on pass. */ static int packet_process_p2p_ipv4(struct zsession *sess, size_t packet_len, struct ip *iph, struct l4_data *l4, enum flow_dir flow_dir) { if (PROTO_MAX == l4->proto) { return 0; } uint16_t port = ntohs((DIR_UP == flow_dir) ? *l4->dst_port : *l4->src_port); pthread_rwlock_rdlock(&sess->lock_client); // p2p police enabled and port greater than 1024 and not whitelisted if (sess->client->p2p_policy && (port >= 1024) && !utarray_find(&zcfg()->p2p_ports_whitelist, &port, uint16_cmp)) { uint64_t speed = spdm_calc(&sess->client->speed[flow_dir]); // 1/4 of bw limit uint64_t throttle_speed = token_bucket_get_max(&sess->client->band[flow_dir]) / 4; uint64_t diff = zclock(false) - sess->client->last_p2p_throttle; if ((speed > throttle_speed) || (diff < P2P_THROTTLE_TIME)) { unsigned upstream_id = IPTOS_DSCP(iph->ip_tos) >> 2; struct token_bucket *bucket = &zinst()->upstreams[upstream_id].band[flow_dir]; if (0 != token_bucket_update(bucket, packet_len)) { return -1; } struct speed_meter *spd = &zinst()->upstreams[upstream_id].speed[flow_dir]; spdm_update(spd, packet_len); diff = zclock(false) - atomic_load_explicit(&sess->client->last_p2p_throttle, memory_order_acquire); if (diff > P2P_THROTTLE_TIME) { atomic_store_explicit(&sess->client->last_p2p_throttle, zclock(false), memory_order_release); } }
/** * Check whether port is allowed. * @param[in] fire Firewall handlel. * @param[in] proto Protocol. * @param[in] port Port to check (network order). * @return Zero on allow. */ int zfwall_allowed(struct zfirewall *fire, enum ipproto proto, uint16_t port) { int ret = -1; pthread_spin_lock(&fire->lock); if ((!utarray_len(&fire->rules[proto][PORT_ALLOW]) || utarray_find(&fire->rules[proto][PORT_ALLOW], &port, uint16_cmp)) && (!utarray_len(&fire->rules[proto][PORT_DENY]) || !utarray_find(&fire->rules[proto][PORT_DENY], &port, uint16_cmp)) ) { ret = 0; } pthread_spin_unlock(&fire->lock); return ret; }
bool zsubnet_group_ip_belongs(const zsubnet_group_t *group, uint32_t ip) { if (!utarray_len(group)) { return false; } ip_range_t ipr_dummy; ipr_dummy.ip_start = ipr_dummy.ip_end = ip; const struct ip_range *ipr_search = utarray_find(group, &ipr_dummy, ip_range_cmp); return (ipr_search != NULL); }
/** * Add firewall rule. * @param[in] fire Firewall handle. * @param[in] proto Protocol. * @param[in] rule Rule type. * @param[in] port Port number (network order). */ void zfwall_add_rule(struct zfirewall *fire, enum ipproto proto, enum port_rule rule, uint16_t port) { pthread_spin_lock(&fire->lock); if (NULL == utarray_find(&fire->rules[proto][rule], &port, uint16_cmp)) { utarray_push_back(&fire->rules[proto][rule], &port); utarray_sort(&fire->rules[proto][rule], uint16_cmp); } pthread_spin_unlock(&fire->lock); }
/** * Delete firewall rule. * @param[in] fire Firewall handle. * @param[in] proto Protocol. * @param[in] rule Rule type. * @param[in] port Port number (network order). */ void zfwall_del_rule(struct zfirewall *fire, enum ipproto proto, enum port_rule rule, uint16_t port) { pthread_spin_lock(&fire->lock); uint16_t *ptr = utarray_find(&fire->rules[proto][rule], &port, uint16_cmp); if (NULL != ptr) { size_t idx = utarray_eltidx(&fire->rules[proto][rule], ptr); utarray_erase(&fire->rules[proto][rule], idx, 1); } pthread_spin_unlock(&fire->lock); }
/** * Locate the modified parameter structure for a parameter, if it exists. * * @param param The parameter being searched. * @return The structure holding the modified value, or * NULL if the parameter has not been modified. */ static struct param_wbuf_s * param_find_changed(param_t param) { struct param_wbuf_s *s = NULL; param_assert_locked(); if (param_values != NULL) { struct param_wbuf_s key; key.param = param; s = utarray_find(param_values, &key, param_compare_values); } return s; }