Skip to content

Commit

Permalink
Merge pull request freeswitch#97 from freeswitch/max_recv_requests_pe…
Browse files Browse the repository at this point in the history
…r_second

Implement maximum receiving requests per second NTATAG_MAX_RECV_REQUESTS_PER_SECOND tag.
  • Loading branch information
andywolk authored Oct 14, 2021
2 parents bf1ae9d + deae6b0 commit a466920
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 2 deletions.
46 changes: 44 additions & 2 deletions libsofia-sip-ua/nta/nta.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ struct nta_agent_s
unsigned sa_bad_resp_mask; /**< Response error mask */
usize_t sa_maxsize; /**< Maximum size of incoming messages */
usize_t sa_max_proceeding; /**< Maximum size of proceeding queue */
usize_t sa_max_recv_requests_per_second; /**< Maximum receiving requests per second */

unsigned sa_udp_mtu; /**< Maximum size of outgoing UDP requests */

Expand Down Expand Up @@ -308,6 +309,13 @@ struct nta_agent_s
usize_t as_tout_response;
} sa_stats[1];

/** Current load in receiving messages per second */
struct {
usize_t as_recv_request_last;
su_time_t last_time;
unsigned requests_per_second;
} sa_load[1];

/** Hash of dialogs. */
leg_htable_t sa_dialogs[1];
/** Default leg */
Expand Down Expand Up @@ -1456,6 +1464,7 @@ int agent_set_params(nta_agent_t *agent, tagi_t *tags)
unsigned bad_resp_mask = agent->sa_bad_resp_mask;
usize_t maxsize = agent->sa_maxsize;
usize_t max_proceeding = agent->sa_max_proceeding;
usize_t max_recv_requests_per_second = agent->sa_max_recv_requests_per_second;
unsigned max_forwards = agent->sa_max_forwards->mf_count;
unsigned udp_mtu = agent->sa_udp_mtu;
unsigned sip_t1 = agent->sa_t1;
Expand Down Expand Up @@ -1514,6 +1523,7 @@ int agent_set_params(nta_agent_t *agent, tagi_t *tags)
NTATAG_GRAYLIST_REF(graylist),
NTATAG_MAXSIZE_REF(maxsize),
NTATAG_MAX_PROCEEDING_REF(max_proceeding),
NTATAG_MAX_RECV_REQUESTS_PER_SECOND_REF(max_recv_requests_per_second),
NTATAG_MAX_FORWARDS_REF(max_forwards),
NTATAG_MCLASS_REF(mclass),
NTATAG_MERGE_482_REF(merge_482),
Expand Down Expand Up @@ -1624,6 +1634,8 @@ int agent_set_params(nta_agent_t *agent, tagi_t *tags)

if (max_proceeding == 0) max_proceeding = USIZE_MAX;
agent->sa_max_proceeding = max_proceeding;

agent->sa_max_recv_requests_per_second = max_recv_requests_per_second;

if (max_forwards == 0) max_forwards = 70; /* Default value */
agent->sa_max_forwards->mf_count = max_forwards;
Expand Down Expand Up @@ -1802,6 +1814,7 @@ int agent_get_params(nta_agent_t *agent, tagi_t *tags)
NTATAG_GRAYLIST(agent->sa_graylist),
NTATAG_MAXSIZE(agent->sa_maxsize),
NTATAG_MAX_PROCEEDING(agent->sa_max_proceeding),
NTATAG_MAX_RECV_REQUESTS_PER_SECOND(agent->sa_max_recv_requests_per_second),
NTATAG_MAX_FORWARDS(agent->sa_max_forwards->mf_count),
NTATAG_MCLASS(agent->sa_mclass),
NTATAG_MERGE_482(agent->sa_merge_482),
Expand Down Expand Up @@ -2899,14 +2912,43 @@ void agent_recv_request(nta_agent_t *agent,
unsigned cseq = sip->sip_cseq ? sip->sip_cseq->cs_seq : 0;
int insane, errors, stream;
unsigned compressed = 0;
su_duration_t sa_load_elapsed_ms = su_duration(su_now(), agent->sa_load->last_time);

agent->sa_stats->as_recv_msg++;
agent->sa_stats->as_recv_request++;

SU_DEBUG_5(("nta: received %s " URL_PRINT_FORMAT " %s (CSeq %u)\n",
if (agent->sa_load->requests_per_second == 0) agent->sa_load->requests_per_second = 1;

if (sa_load_elapsed_ms >= 1000) {
if (agent->sa_load->as_recv_request_last) {
agent->sa_load->requests_per_second = ((agent->sa_stats->as_recv_request - agent->sa_load->as_recv_request_last) * 1000) / sa_load_elapsed_ms;
}

/** Update */
agent->sa_load->last_time = su_now();
agent->sa_load->as_recv_request_last = agent->sa_stats->as_recv_request;

if (agent->sa_max_recv_requests_per_second && agent->sa_load->requests_per_second > agent->sa_max_recv_requests_per_second) {
SU_DEBUG_5(("SIP flood: Dropped %u incoming SIP messages, %u message / sec (of %u allowed)\n",
agent->sa_stats->as_drop_request + 1, agent->sa_load->requests_per_second, agent->sa_max_recv_requests_per_second));
}

} else if (sa_load_elapsed_ms == -SU_DURATION_MAX) {
/** Initialize */
agent->sa_load->last_time = su_now();
agent->sa_load->as_recv_request_last = agent->sa_stats->as_recv_request;
}

if (agent->sa_max_recv_requests_per_second && agent->sa_load->requests_per_second > agent->sa_max_recv_requests_per_second) {
agent->sa_stats->as_drop_request++;
msg_destroy(msg);
return;
}

SU_DEBUG_5(("nta: received %s " URL_PRINT_FORMAT " %s (CSeq %u) (load: %u rps)\n",
method_name,
URL_PRINT_ARGS(sip->sip_request->rq_url),
sip->sip_request->rq_version, cseq));
sip->sip_request->rq_version, cseq, agent->sa_load->requests_per_second));

if (agent->sa_drop_prob && !tport_is_reliable(tport)) {
if ((unsigned)su_randint(0, 1000) < agent->sa_drop_prob) {
Expand Down
20 changes: 20 additions & 0 deletions libsofia-sip-ua/nta/nta_tag.c
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,26 @@ tag_typedef_t ntatag_maxsize = USIZETAG_TYPEDEF(maxsize);
*/
tag_typedef_t ntatag_max_proceeding = USIZETAG_TYPEDEF(max_proceeding);

/**@def NTATAG_MAX_RECV_REQUESTS_PER_SECOND(x)
*
* Maximum receiving requests per second.
*
* Messages will start dropping when this threshold reaches.
*
* @par Used with
* nua_create(), nua_set_params(),
* nta_agent_create(), nta_agent_set_params()
*
* @par Parameter type
* - #usize_t
*
* @par Values
* - Maximum receiving requests per second (size_t).
*
* @NEW_1_13_6
*/
tag_typedef_t ntatag_max_recv_requests_per_second = USIZETAG_TYPEDEF(max_recv_requests_per_second);

/**@def NTATAG_UDP_MTU(x)
*
* Maximum size of outgoing UDP request.
Expand Down
6 changes: 6 additions & 0 deletions libsofia-sip-ua/nta/sofia-sip/nta_tag.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,12 @@ NTA_DLL extern tag_typedef_t ntatag_max_proceeding;
NTA_DLL extern tag_typedef_t ntatag_max_proceeding_ref;
#define NTATAG_MAX_PROCEEDING_REF(x) ntatag_max_proceeding_ref, tag_usize_vr(&(x))

NTA_DLL extern tag_typedef_t ntatag_max_recv_requests_per_second;
#define NTATAG_MAX_RECV_REQUESTS_PER_SECOND(x) ntatag_max_recv_requests_per_second, tag_usize_v((x))

NTA_DLL extern tag_typedef_t ntatag_max_recv_requests_per_second_ref;
#define NTATAG_MAX_RECV_REQUESTS_PER_SECOND_REF(x) ntatag_max_recv_requests_per_second_ref, tag_usize_vr(&(x))

NTA_DLL extern tag_typedef_t ntatag_max_forwards;
#define NTATAG_MAX_FORWARDS(x) ntatag_max_forwards, tag_uint_v((x))

Expand Down
3 changes: 3 additions & 0 deletions libsofia-sip-ua/nua/nua_params.c
Original file line number Diff line number Diff line change
Expand Up @@ -1595,6 +1595,7 @@ int nua_stack_get_params(nua_t *nua, nua_handle_t *nh, nua_event_t e,
/* nta */
unsigned udp_mtu = 0;
usize_t max_proceeding = 0;
usize_t max_recv_requests_per_second = 0;
unsigned sip_t1 = 0, sip_t2 = 0, sip_t4 = 0, sip_t1x64 = 0;
unsigned debug_drop_prob = 0;
url_string_t const *proxy = NULL;
Expand All @@ -1612,6 +1613,7 @@ int nua_stack_get_params(nua_t *nua, nua_handle_t *nh, nua_event_t e,
nta_agent_get_params(nua->nua_nta,
NTATAG_UDP_MTU_REF(udp_mtu),
NTATAG_MAX_PROCEEDING_REF(max_proceeding),
NTATAG_MAX_PROCEEDING_REF(max_recv_requests_per_second),
NTATAG_SIP_T1_REF(sip_t1),
NTATAG_SIP_T2_REF(sip_t2),
NTATAG_SIP_T4_REF(sip_t4),
Expand Down Expand Up @@ -1768,6 +1770,7 @@ int nua_stack_get_params(nua_t *nua, nua_handle_t *nh, nua_event_t e,

NTATAG_UDP_MTU(udp_mtu),
NTATAG_MAX_PROCEEDING(max_proceeding),
NTATAG_MAX_RECV_REQUESTS_PER_SECOND(max_recv_requests_per_second),
NTATAG_SIP_T1(sip_t1),
NTATAG_SIP_T2(sip_t2),
NTATAG_SIP_T4(sip_t4),
Expand Down

0 comments on commit a466920

Please sign in to comment.