freetdm: call rate limit
This commit is contained in:
parent
889cadb8aa
commit
a1fe7c8de4
|
@ -38,6 +38,7 @@
|
||||||
#define __FUNCTION__ __SWITCH_FUNC__
|
#define __FUNCTION__ __SWITCH_FUNC__
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define FREETDM_LIMIT_REALM "__freetdm"
|
||||||
#define FREETDM_VAR_PREFIX "freetdm_"
|
#define FREETDM_VAR_PREFIX "freetdm_"
|
||||||
#define FREETDM_VAR_PREFIX_LEN 8
|
#define FREETDM_VAR_PREFIX_LEN 8
|
||||||
|
|
||||||
|
@ -55,6 +56,11 @@ typedef enum {
|
||||||
ANALOG_OPTION_CALL_SWAP = (1 << 1)
|
ANALOG_OPTION_CALL_SWAP = (1 << 1)
|
||||||
} analog_option_t;
|
} analog_option_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
FTDM_LIMIT_RESET_ON_TIMEOUT = 0,
|
||||||
|
FTDM_LIMIT_RESET_ON_ANSWER = 1
|
||||||
|
} limit_reset_event_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
TFLAG_IO = (1 << 0),
|
TFLAG_IO = (1 << 0),
|
||||||
TFLAG_DTMF = (1 << 1),
|
TFLAG_DTMF = (1 << 1),
|
||||||
|
@ -119,6 +125,10 @@ struct span_config {
|
||||||
char hold_music[256];
|
char hold_music[256];
|
||||||
char type[256];
|
char type[256];
|
||||||
analog_option_t analog_options;
|
analog_option_t analog_options;
|
||||||
|
const char *limit_backend;
|
||||||
|
int limit_calls;
|
||||||
|
int limit_seconds;
|
||||||
|
limit_reset_event_t limit_reset_event;
|
||||||
chan_pvt_t pvts[FTDM_MAX_CHANNELS_SPAN];
|
chan_pvt_t pvts[FTDM_MAX_CHANNELS_SPAN];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1292,6 +1302,9 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
|
||||||
switch_caller_profile_t *caller_profile;
|
switch_caller_profile_t *caller_profile;
|
||||||
switch_channel_t *channel = switch_core_session_get_channel(*new_session);
|
switch_channel_t *channel = switch_core_session_get_channel(*new_session);
|
||||||
|
|
||||||
|
span_id = ftdm_channel_get_span_id(ftdmchan);
|
||||||
|
chan_id = ftdm_channel_get_id(ftdmchan);
|
||||||
|
|
||||||
switch_core_session_add_stream(*new_session, NULL);
|
switch_core_session_add_stream(*new_session, NULL);
|
||||||
if ((tech_pvt = (private_t *) switch_core_session_alloc(*new_session, sizeof(private_t))) != 0) {
|
if ((tech_pvt = (private_t *) switch_core_session_alloc(*new_session, sizeof(private_t))) != 0) {
|
||||||
tech_init(tech_pvt, *new_session, ftdmchan);
|
tech_init(tech_pvt, *new_session, ftdmchan);
|
||||||
|
@ -1302,12 +1315,12 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(name, sizeof(name), "FreeTDM/%u:%u/%s", ftdm_channel_get_span_id(ftdmchan), ftdm_channel_get_id(ftdmchan), dest);
|
snprintf(name, sizeof(name), "FreeTDM/%u:%u/%s", span_id, chan_id, dest);
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connect outbound channel %s\n", name);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connect outbound channel %s\n", name);
|
||||||
switch_channel_set_name(channel, name);
|
switch_channel_set_name(channel, name);
|
||||||
switch_channel_set_variable(channel, "freetdm_span_name", ftdm_channel_get_span_name(ftdmchan));
|
switch_channel_set_variable(channel, "freetdm_span_name", ftdm_channel_get_span_name(ftdmchan));
|
||||||
switch_channel_set_variable_printf(channel, "freetdm_span_number", "%d", ftdm_channel_get_span_id(ftdmchan));
|
switch_channel_set_variable_printf(channel, "freetdm_span_number", "%d", span_id);
|
||||||
switch_channel_set_variable_printf(channel, "freetdm_chan_number", "%d", ftdm_channel_get_id(ftdmchan));
|
switch_channel_set_variable_printf(channel, "freetdm_chan_number", "%d", chan_id);
|
||||||
ftdm_channel_set_caller_data(ftdmchan, &caller_data);
|
ftdm_channel_set_caller_data(ftdmchan, &caller_data);
|
||||||
caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
|
caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
|
||||||
caller_profile->destination_number = switch_core_strdup(caller_profile->pool, switch_str_nil(dest_num));
|
caller_profile->destination_number = switch_core_strdup(caller_profile->pool, switch_str_nil(dest_num));
|
||||||
|
@ -1325,6 +1338,18 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (SPAN_CONFIG[span_id].limit_calls) {
|
||||||
|
char spanresource[512];
|
||||||
|
snprintf(spanresource, sizeof(spanresource), "span_%s_%s", ftdm_channel_get_span_name(ftdmchan), caller_data.dnis.digits);
|
||||||
|
ftdm_log(FTDM_LOG_DEBUG, "Adding rate limit resource on channel %d:%d (%s/%s/%d/%d)\n", span_id, chan_id, FREETDM_LIMIT_REALM,
|
||||||
|
spanresource, SPAN_CONFIG[span_id].limit_calls, SPAN_CONFIG[span_id].limit_seconds);
|
||||||
|
if (switch_limit_incr("hash", *new_session, FREETDM_LIMIT_REALM, spanresource, SPAN_CONFIG[span_id].limit_calls, SPAN_CONFIG[span_id].limit_seconds) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_core_session_destroy(new_session);
|
||||||
|
cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((status = ftdm_channel_call_place(ftdmchan)) != FTDM_SUCCESS) {
|
if ((status = ftdm_channel_call_place(ftdmchan)) != FTDM_SUCCESS) {
|
||||||
if (tech_pvt->read_codec.implementation) {
|
if (tech_pvt->read_codec.implementation) {
|
||||||
switch_core_codec_destroy(&tech_pvt->read_codec);
|
switch_core_codec_destroy(&tech_pvt->read_codec);
|
||||||
|
@ -1516,6 +1541,18 @@ static FIO_SIGNAL_CB_FUNCTION(on_common_signal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case FTDM_SIGEVENT_UP:
|
||||||
|
{
|
||||||
|
/* clear any rate limit resource for this span */
|
||||||
|
char spanresource[512];
|
||||||
|
if (SPAN_CONFIG[spanid].limit_reset_event == FTDM_LIMIT_RESET_ON_ANSWER && SPAN_CONFIG[spanid].limit_calls) {
|
||||||
|
ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(sigmsg->channel);
|
||||||
|
snprintf(spanresource, sizeof(spanresource), "span_%s_%s", ftdm_channel_get_span_name(sigmsg->channel), caller_data->dnis.digits);
|
||||||
|
ftdm_log(FTDM_LOG_DEBUG, "Clearing rate limit resource on channel %d:%d (%s/%s)\n", spanid, chanid, FREETDM_LIMIT_REALM, spanresource);
|
||||||
|
switch_limit_interval_reset("hash", FREETDM_LIMIT_REALM, spanresource);
|
||||||
|
}
|
||||||
|
return FTDM_SUCCESS;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return FTDM_SUCCESS;
|
return FTDM_SUCCESS;
|
||||||
break;
|
break;
|
||||||
|
@ -2344,7 +2381,7 @@ static switch_status_t load_config(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((spans = switch_xml_child(cfg, "sangoma_isdn_spans"))) {
|
if ((spans = switch_xml_child(cfg, "sangoma_pri_spans")) || (spans = switch_xml_child(cfg, "sangoma_bri_spans"))) {
|
||||||
for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) {
|
for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) {
|
||||||
ftdm_status_t zstatus = FTDM_FAIL;
|
ftdm_status_t zstatus = FTDM_FAIL;
|
||||||
const char *context = "default";
|
const char *context = "default";
|
||||||
|
@ -2362,11 +2399,6 @@ static switch_status_t load_config(void)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!configname) {
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sangoma isdn span missing required attribute, skipping ...\n");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (name) {
|
if (name) {
|
||||||
zstatus = ftdm_span_find_by_name(name, &span);
|
zstatus = ftdm_span_find_by_name(name, &span);
|
||||||
} else {
|
} else {
|
||||||
|
@ -2399,6 +2431,10 @@ static switch_status_t load_config(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* some defaults first */
|
||||||
|
SPAN_CONFIG[span_id].limit_backend = "hash";
|
||||||
|
SPAN_CONFIG[span_id].limit_reset_event = FTDM_LIMIT_RESET_ON_TIMEOUT;
|
||||||
|
|
||||||
for (param = switch_xml_child(myspan, "param"); param; param = param->next) {
|
for (param = switch_xml_child(myspan, "param"); param; param = param->next) {
|
||||||
char *var = (char *) switch_xml_attr_soft(param, "name");
|
char *var = (char *) switch_xml_attr_soft(param, "name");
|
||||||
char *val = (char *) switch_xml_attr_soft(param, "value");
|
char *val = (char *) switch_xml_attr_soft(param, "value");
|
||||||
|
@ -2412,6 +2448,28 @@ static switch_status_t load_config(void)
|
||||||
context = val;
|
context = val;
|
||||||
} else if (!strcasecmp(var, "dialplan")) {
|
} else if (!strcasecmp(var, "dialplan")) {
|
||||||
dialplan = val;
|
dialplan = val;
|
||||||
|
} else if (!strcasecmp(var, "call_limit_backend")) {
|
||||||
|
SPAN_CONFIG[span_id].limit_backend = val;
|
||||||
|
ftdm_log(FTDM_LOG_DEBUG, "Using limit backend %s for span %d\n", SPAN_CONFIG[span_id].limit_backend, span_id);
|
||||||
|
} else if (!strcasecmp(var, "call_limit_rate")) {
|
||||||
|
int calls;
|
||||||
|
int seconds;
|
||||||
|
if (sscanf(val, "%d/%d", &calls, &seconds) != 2) {
|
||||||
|
ftdm_log(FTDM_LOG_ERROR, "Invalid %s parameter, format example: 3/1 for 3 calls per second\n", var);
|
||||||
|
} else {
|
||||||
|
if (calls < 1 || seconds < 1) {
|
||||||
|
ftdm_log(FTDM_LOG_ERROR, "Invalid %s parameter value, minimum call limit must be 1 per second\n", var);
|
||||||
|
} else {
|
||||||
|
SPAN_CONFIG[span_id].limit_calls = calls;
|
||||||
|
SPAN_CONFIG[span_id].limit_seconds = seconds;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (!strcasecmp(var, "call_limit_reset_event")) {
|
||||||
|
if (!strcasecmp(val, "answer")) {
|
||||||
|
SPAN_CONFIG[span_id].limit_reset_event = FTDM_LIMIT_RESET_ON_ANSWER;
|
||||||
|
} else {
|
||||||
|
ftdm_log(FTDM_LOG_ERROR, "Invalid %s parameter value, only accepted event is 'answer'\n", var);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
spanparameters[paramindex].var = var;
|
spanparameters[paramindex].var = var;
|
||||||
spanparameters[paramindex].val = val;
|
spanparameters[paramindex].val = val;
|
||||||
|
|
Loading…
Reference in New Issue