mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-05 20:20:07 +00:00
res_pjsip: Add new AOR option "qualify_2xx_only"
Added a new option "qualify_2xx_only" to the res_pjsip AOR qualify feature to mark a contact as available only if an OPTIONS request returns a 2XX response. If the option is not specified or is false, any response to the OPTIONS request marks the contact as available. UserNote: The pjsip.conf AOR section now has a "qualify_2xx_only" option that can be set so that only 2XX responses to OPTIONS requests used to qualify a contact will mark the contact as available.
This commit is contained in:
committed by
asterisk-org-access-app[bot]
parent
f36a736a0c
commit
3dee037446
@@ -1219,6 +1219,8 @@
|
|||||||
;qualify_frequency=0 ; Interval at which to qualify an AoR via OPTIONS requests.
|
;qualify_frequency=0 ; Interval at which to qualify an AoR via OPTIONS requests.
|
||||||
; (default: "0")
|
; (default: "0")
|
||||||
;qualify_timeout=3.0 ; Qualify timeout in fractional seconds (default: "3.0")
|
;qualify_timeout=3.0 ; Qualify timeout in fractional seconds (default: "3.0")
|
||||||
|
;qualify_2xx_only=no ; If true, only qualify AoR if OPTIONS request returns 2XX
|
||||||
|
; (default: "no")
|
||||||
;authenticate_qualify=no ; Authenticates a qualify request if needed
|
;authenticate_qualify=no ; Authenticates a qualify request if needed
|
||||||
; (default: "no")
|
; (default: "no")
|
||||||
;outbound_proxy= ; Proxy through which to send OPTIONS requests, a full SIP URI
|
;outbound_proxy= ; Proxy through which to send OPTIONS requests, a full SIP URI
|
||||||
|
@@ -0,0 +1,34 @@
|
|||||||
|
"""add qualify 2xx only option
|
||||||
|
|
||||||
|
Revision ID: 44bd6dd914fa
|
||||||
|
Revises: 4f91fc18c979
|
||||||
|
Create Date: 2024-12-02 21:08:41.130023
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = '44bd6dd914fa'
|
||||||
|
down_revision = '4f91fc18c979'
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy.dialects.postgresql import ENUM
|
||||||
|
|
||||||
|
AST_BOOL_NAME = 'ast_bool_values'
|
||||||
|
AST_BOOL_VALUES = [ '0', '1',
|
||||||
|
'off', 'on',
|
||||||
|
'false', 'true',
|
||||||
|
'no', 'yes' ]
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
ast_bool_values = ENUM(*AST_BOOL_VALUES, name=AST_BOOL_NAME, create_type=False)
|
||||||
|
op.add_column('ps_aors', sa.Column('qualify_2xx_only', ast_bool_values))
|
||||||
|
op.add_column('ps_contacts', sa.Column('qualify_2xx_only', ast_bool_values))
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
if op.get_context().bind.dialect.name == 'mssql':
|
||||||
|
op.drop_constraint('ck_ps_aors_qualify_2xx_only_ast_bool_values', 'ps_aors')
|
||||||
|
op.drop_constraint('ck_ps_contacts_qualify_2xx_only_ast_bool_values', 'ps_contacts')
|
||||||
|
op.drop_column('ps_aors', 'qualify_2xx_only')
|
||||||
|
op.drop_column('ps_contacts', 'qualify_2xx_only')
|
@@ -423,6 +423,8 @@ struct ast_sip_contact {
|
|||||||
int via_port;
|
int via_port;
|
||||||
/*! If true delete the contact on Asterisk restart/boot */
|
/*! If true delete the contact on Asterisk restart/boot */
|
||||||
int prune_on_boot;
|
int prune_on_boot;
|
||||||
|
/*! If true only authenticate if OPTIONS response is 2XX */
|
||||||
|
int qualify_2xx_only;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -505,6 +507,8 @@ struct ast_sip_aor {
|
|||||||
char *voicemail_extension;
|
char *voicemail_extension;
|
||||||
/*! Whether to remove unavailable contacts over max_contacts at all or first if remove_existing is enabled */
|
/*! Whether to remove unavailable contacts over max_contacts at all or first if remove_existing is enabled */
|
||||||
unsigned int remove_unavailable;
|
unsigned int remove_unavailable;
|
||||||
|
/*! If true only authenticate if OPTIONS response is 2XX */
|
||||||
|
int qualify_2xx_only;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@@ -373,6 +373,7 @@ struct ast_sip_contact *ast_sip_location_create_contact(struct ast_sip_aor *aor,
|
|||||||
contact->expiration_time = expiration_time;
|
contact->expiration_time = expiration_time;
|
||||||
contact->qualify_frequency = aor->qualify_frequency;
|
contact->qualify_frequency = aor->qualify_frequency;
|
||||||
contact->qualify_timeout = aor->qualify_timeout;
|
contact->qualify_timeout = aor->qualify_timeout;
|
||||||
|
contact->qualify_2xx_only = aor->qualify_2xx_only;
|
||||||
contact->authenticate_qualify = aor->authenticate_qualify;
|
contact->authenticate_qualify = aor->authenticate_qualify;
|
||||||
if (path_info && aor->support_path) {
|
if (path_info && aor->support_path) {
|
||||||
ast_string_field_set(contact, path, path_info);
|
ast_string_field_set(contact, path, path_info);
|
||||||
@@ -1394,6 +1395,7 @@ int ast_sip_initialize_sorcery_location(void)
|
|||||||
ast_sorcery_object_field_register(sorcery, "contact", "qualify_frequency", 0, OPT_UINT_T,
|
ast_sorcery_object_field_register(sorcery, "contact", "qualify_frequency", 0, OPT_UINT_T,
|
||||||
PARSE_IN_RANGE, FLDSET(struct ast_sip_contact, qualify_frequency), 0, 86400);
|
PARSE_IN_RANGE, FLDSET(struct ast_sip_contact, qualify_frequency), 0, 86400);
|
||||||
ast_sorcery_object_field_register(sorcery, "contact", "qualify_timeout", "3.0", OPT_DOUBLE_T, 0, FLDSET(struct ast_sip_contact, qualify_timeout));
|
ast_sorcery_object_field_register(sorcery, "contact", "qualify_timeout", "3.0", OPT_DOUBLE_T, 0, FLDSET(struct ast_sip_contact, qualify_timeout));
|
||||||
|
ast_sorcery_object_field_register(sorcery, "contact", "qualify_2xx_only", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_contact, qualify_2xx_only));
|
||||||
ast_sorcery_object_field_register(sorcery, "contact", "authenticate_qualify", "no", OPT_YESNO_T, 1, FLDSET(struct ast_sip_contact, authenticate_qualify));
|
ast_sorcery_object_field_register(sorcery, "contact", "authenticate_qualify", "no", OPT_YESNO_T, 1, FLDSET(struct ast_sip_contact, authenticate_qualify));
|
||||||
ast_sorcery_object_field_register(sorcery, "contact", "outbound_proxy", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, outbound_proxy));
|
ast_sorcery_object_field_register(sorcery, "contact", "outbound_proxy", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, outbound_proxy));
|
||||||
ast_sorcery_object_field_register(sorcery, "contact", "user_agent", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, user_agent));
|
ast_sorcery_object_field_register(sorcery, "contact", "user_agent", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, user_agent));
|
||||||
@@ -1410,6 +1412,7 @@ int ast_sip_initialize_sorcery_location(void)
|
|||||||
ast_sorcery_object_field_register(sorcery, "aor", "default_expiration", "3600", OPT_UINT_T, 0, FLDSET(struct ast_sip_aor, default_expiration));
|
ast_sorcery_object_field_register(sorcery, "aor", "default_expiration", "3600", OPT_UINT_T, 0, FLDSET(struct ast_sip_aor, default_expiration));
|
||||||
ast_sorcery_object_field_register(sorcery, "aor", "qualify_frequency", 0, OPT_UINT_T, PARSE_IN_RANGE, FLDSET(struct ast_sip_aor, qualify_frequency), 0, 86400);
|
ast_sorcery_object_field_register(sorcery, "aor", "qualify_frequency", 0, OPT_UINT_T, PARSE_IN_RANGE, FLDSET(struct ast_sip_aor, qualify_frequency), 0, 86400);
|
||||||
ast_sorcery_object_field_register(sorcery, "aor", "qualify_timeout", "3.0", OPT_DOUBLE_T, 0, FLDSET(struct ast_sip_aor, qualify_timeout));
|
ast_sorcery_object_field_register(sorcery, "aor", "qualify_timeout", "3.0", OPT_DOUBLE_T, 0, FLDSET(struct ast_sip_aor, qualify_timeout));
|
||||||
|
ast_sorcery_object_field_register(sorcery, "aor", "qualify_2xx_only", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_aor, qualify_2xx_only));
|
||||||
ast_sorcery_object_field_register(sorcery, "aor", "authenticate_qualify", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_aor, authenticate_qualify));
|
ast_sorcery_object_field_register(sorcery, "aor", "authenticate_qualify", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_aor, authenticate_qualify));
|
||||||
ast_sorcery_object_field_register(sorcery, "aor", "max_contacts", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_aor, max_contacts));
|
ast_sorcery_object_field_register(sorcery, "aor", "max_contacts", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_aor, max_contacts));
|
||||||
ast_sorcery_object_field_register(sorcery, "aor", "remove_existing", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_aor, remove_existing));
|
ast_sorcery_object_field_register(sorcery, "aor", "remove_existing", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_aor, remove_existing));
|
||||||
|
@@ -1966,6 +1966,14 @@
|
|||||||
If <literal>0</literal> no timeout. Time in fractional seconds.
|
If <literal>0</literal> no timeout. Time in fractional seconds.
|
||||||
</para></description>
|
</para></description>
|
||||||
</configOption>
|
</configOption>
|
||||||
|
<configOption name="qualify_2xx_only">
|
||||||
|
<synopsis>Only qualify contact if OPTIONS request returns 2XX</synopsis>
|
||||||
|
<description>
|
||||||
|
<para>If true only mark a contact as available if the qualify OPTIONS
|
||||||
|
request receives a 2XX response.
|
||||||
|
</para>
|
||||||
|
</description>
|
||||||
|
</configOption>
|
||||||
<configOption name="authenticate_qualify">
|
<configOption name="authenticate_qualify">
|
||||||
<synopsis>Authenticates a qualify challenge response if needed</synopsis>
|
<synopsis>Authenticates a qualify challenge response if needed</synopsis>
|
||||||
<description>
|
<description>
|
||||||
@@ -2192,6 +2200,14 @@
|
|||||||
If <literal>0</literal> no timeout. Time in fractional seconds.
|
If <literal>0</literal> no timeout. Time in fractional seconds.
|
||||||
</para></description>
|
</para></description>
|
||||||
</configOption>
|
</configOption>
|
||||||
|
<configOption name="qualify_2xx_only">
|
||||||
|
<synopsis>Only qualify contact if OPTIONS request returns 2XX</synopsis>
|
||||||
|
<description>
|
||||||
|
<para>If true only mark a contact as available if the qualify OPTIONS
|
||||||
|
request receives a 2XX response.
|
||||||
|
</para>
|
||||||
|
</description>
|
||||||
|
</configOption>
|
||||||
<configOption name="authenticate_qualify">
|
<configOption name="authenticate_qualify">
|
||||||
<synopsis>Authenticates a qualify challenge response if needed</synopsis>
|
<synopsis>Authenticates a qualify challenge response if needed</synopsis>
|
||||||
<description>
|
<description>
|
||||||
|
@@ -180,6 +180,8 @@ struct sip_options_aor {
|
|||||||
unsigned int available;
|
unsigned int available;
|
||||||
/*! \brief Frequency to send OPTIONS requests to AOR contacts. 0 is disabled. */
|
/*! \brief Frequency to send OPTIONS requests to AOR contacts. 0 is disabled. */
|
||||||
unsigned int qualify_frequency;
|
unsigned int qualify_frequency;
|
||||||
|
/*! \brief If true only authenticate if OPTIONS response is 2XX */
|
||||||
|
int qualify_2xx_only;
|
||||||
/*! If true authenticate the qualify challenge response if needed */
|
/*! If true authenticate the qualify challenge response if needed */
|
||||||
int authenticate_qualify;
|
int authenticate_qualify;
|
||||||
/*! \brief Qualify timeout. 0 is diabled. */
|
/*! \brief Qualify timeout. 0 is diabled. */
|
||||||
@@ -799,7 +801,12 @@ static void qualify_contact_cb(void *token, pjsip_event *e)
|
|||||||
status = UNAVAILABLE;
|
status = UNAVAILABLE;
|
||||||
break;
|
break;
|
||||||
case PJSIP_EVENT_RX_MSG:
|
case PJSIP_EVENT_RX_MSG:
|
||||||
status = AVAILABLE;
|
if (contact_callback_data->aor_options->qualify_2xx_only &&
|
||||||
|
(e->body.tsx_state.tsx->status_code < 200 || e->body.tsx_state.tsx->status_code >= 300)) {
|
||||||
|
status = UNAVAILABLE;
|
||||||
|
} else {
|
||||||
|
status = AVAILABLE;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1341,6 +1348,7 @@ static void sip_options_apply_aor_configuration(struct sip_options_aor *aor_opti
|
|||||||
}
|
}
|
||||||
|
|
||||||
aor_options->authenticate_qualify = aor->authenticate_qualify;
|
aor_options->authenticate_qualify = aor->authenticate_qualify;
|
||||||
|
aor_options->qualify_2xx_only = aor->qualify_2xx_only;
|
||||||
aor_options->qualify_timeout = aor->qualify_timeout;
|
aor_options->qualify_timeout = aor->qualify_timeout;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2082,6 +2090,7 @@ static int has_qualify_changed (const struct ast_sip_contact *contact, const str
|
|||||||
}
|
}
|
||||||
} else if (contact->qualify_frequency != aor_options->qualify_frequency
|
} else if (contact->qualify_frequency != aor_options->qualify_frequency
|
||||||
|| contact->authenticate_qualify != aor_options->authenticate_qualify
|
|| contact->authenticate_qualify != aor_options->authenticate_qualify
|
||||||
|
|| contact->qualify_2xx_only != aor_options->qualify_2xx_only
|
||||||
|| ((int)(contact->qualify_timeout * 1000)) != ((int)(aor_options->qualify_timeout * 1000))) {
|
|| ((int)(contact->qualify_timeout * 1000)) != ((int)(aor_options->qualify_timeout * 1000))) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -2530,6 +2539,7 @@ static char *cli_show_qualify_endpoint(struct ast_cli_entry *e, int cmd, struct
|
|||||||
ast_cli(a->fd, " * AOR '%s' on endpoint '%s'\n", aor_name, endpoint_name);
|
ast_cli(a->fd, " * AOR '%s' on endpoint '%s'\n", aor_name, endpoint_name);
|
||||||
ast_cli(a->fd, " Qualify frequency : %d sec\n", aor_options->qualify_frequency);
|
ast_cli(a->fd, " Qualify frequency : %d sec\n", aor_options->qualify_frequency);
|
||||||
ast_cli(a->fd, " Qualify timeout : %d ms\n", (int)(aor_options->qualify_timeout / 1000));
|
ast_cli(a->fd, " Qualify timeout : %d ms\n", (int)(aor_options->qualify_timeout / 1000));
|
||||||
|
ast_cli(a->fd, " Qualify 2xx only : %s\n", aor_options->qualify_2xx_only ? "yes" : "no");
|
||||||
ast_cli(a->fd, " Authenticate qualify : %s\n", aor_options->authenticate_qualify?"yes":"no");
|
ast_cli(a->fd, " Authenticate qualify : %s\n", aor_options->authenticate_qualify?"yes":"no");
|
||||||
ast_cli(a->fd, "\n");
|
ast_cli(a->fd, "\n");
|
||||||
ao2_ref(aor_options, -1);
|
ao2_ref(aor_options, -1);
|
||||||
@@ -2569,6 +2579,7 @@ static char *cli_show_qualify_aor(struct ast_cli_entry *e, int cmd, struct ast_c
|
|||||||
ast_cli(a->fd, " * AOR '%s'\n", aor_name);
|
ast_cli(a->fd, " * AOR '%s'\n", aor_name);
|
||||||
ast_cli(a->fd, " Qualify frequency : %d sec\n", aor_options->qualify_frequency);
|
ast_cli(a->fd, " Qualify frequency : %d sec\n", aor_options->qualify_frequency);
|
||||||
ast_cli(a->fd, " Qualify timeout : %d ms\n", (int)(aor_options->qualify_timeout / 1000));
|
ast_cli(a->fd, " Qualify timeout : %d ms\n", (int)(aor_options->qualify_timeout / 1000));
|
||||||
|
ast_cli(a->fd, " Qualify 2xx only : %s\n", aor_options->qualify_2xx_only ? "yes" : "no");
|
||||||
ast_cli(a->fd, " Authenticate qualify : %s\n", aor_options->authenticate_qualify?"yes":"no");
|
ast_cli(a->fd, " Authenticate qualify : %s\n", aor_options->authenticate_qualify?"yes":"no");
|
||||||
ao2_ref(aor_options, -1);
|
ao2_ref(aor_options, -1);
|
||||||
|
|
||||||
@@ -2764,6 +2775,7 @@ int ast_sip_format_contact_ami(void *obj, void *arg, int flags)
|
|||||||
ast_str_append(&buf, 0, "Path: %s\r\n", contact->path);
|
ast_str_append(&buf, 0, "Path: %s\r\n", contact->path);
|
||||||
ast_str_append(&buf, 0, "QualifyFrequency: %u\r\n", contact->qualify_frequency);
|
ast_str_append(&buf, 0, "QualifyFrequency: %u\r\n", contact->qualify_frequency);
|
||||||
ast_str_append(&buf, 0, "QualifyTimeout: %.3f\r\n", contact->qualify_timeout);
|
ast_str_append(&buf, 0, "QualifyTimeout: %.3f\r\n", contact->qualify_timeout);
|
||||||
|
ast_str_append(&buf, 0, "Qualify2xxOnly: %d\r\n", contact->qualify_2xx_only);
|
||||||
|
|
||||||
astman_append(ami->s, "%s\r\n", ast_str_buffer(buf));
|
astman_append(ami->s, "%s\r\n", ast_str_buffer(buf));
|
||||||
ami->count++;
|
ami->count++;
|
||||||
|
@@ -913,6 +913,7 @@ static void register_aor_core(pjsip_rx_data *rdata,
|
|||||||
contact_update->expiration_time = ast_tvadd(ast_tvnow(), ast_samp2tv(expiration, 1));
|
contact_update->expiration_time = ast_tvadd(ast_tvnow(), ast_samp2tv(expiration, 1));
|
||||||
contact_update->qualify_frequency = aor->qualify_frequency;
|
contact_update->qualify_frequency = aor->qualify_frequency;
|
||||||
contact_update->authenticate_qualify = aor->authenticate_qualify;
|
contact_update->authenticate_qualify = aor->authenticate_qualify;
|
||||||
|
contact_update->qualify_2xx_only = aor->qualify_2xx_only;
|
||||||
if (path_str) {
|
if (path_str) {
|
||||||
ast_string_field_set(contact_update, path, ast_str_buffer(path_str));
|
ast_string_field_set(contact_update, path, ast_str_buffer(path_str));
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user