From 895c8e0d2c97cd04299f3f179e99d8a3873c06c6 Mon Sep 17 00:00:00 2001 From: Mark Michelson Date: Tue, 30 Jul 2013 15:17:56 +0000 Subject: Reorganize the ast_sip_endpoint structure into substructures. (closes issue ASTERISK-22135) reported by Matt Jordan Review: https://reviewboard.asterisk.org/r/2707 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@395748 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- channels/chan_gulp.c | 41 +-- include/asterisk/res_sip.h | 373 ++++++++++++++++++---------- res/res_sip.c | 6 +- res/res_sip.exports.in | 2 + res/res_sip/sip_configuration.c | 275 +++++++++++--------- res/res_sip/sip_distributor.c | 2 +- res/res_sip/sip_options.c | 3 +- res/res_sip/sip_outbound_auth.c | 2 +- res/res_sip_authenticator_digest.c | 14 +- res/res_sip_caller_id.c | 20 +- res/res_sip_diversion.c | 2 +- res/res_sip_messaging.c | 4 +- res/res_sip_mwi.c | 10 +- res/res_sip_nat.c | 4 +- res/res_sip_one_touch_record_info.c | 6 +- res/res_sip_outbound_authenticator_digest.c | 18 +- res/res_sip_outbound_registration.c | 71 +----- res/res_sip_pubsub.c | 6 +- res/res_sip_sdp_rtp.c | 78 +++--- res/res_sip_session.c | 18 +- res/res_sip_t38.c | 32 +-- 21 files changed, 551 insertions(+), 436 deletions(-) diff --git a/channels/chan_gulp.c b/channels/chan_gulp.c index 95cf072c7..78694e3fa 100644 --- a/channels/chan_gulp.c +++ b/channels/chan_gulp.c @@ -386,11 +386,11 @@ static enum ast_rtp_glue_result gulp_get_rtp_peer(struct ast_channel *chan, stru ao2_ref(*instance, +1); ast_assert(endpoint != NULL); - if (endpoint->media_encryption != AST_SIP_MEDIA_ENCRYPT_NONE) { + if (endpoint->media.rtp.encryption != AST_SIP_MEDIA_ENCRYPT_NONE) { return AST_RTP_GLUE_RESULT_FORBID; } - if (endpoint->direct_media) { + if (endpoint->media.direct_media.enabled) { return AST_RTP_GLUE_RESULT_REMOTE; } @@ -414,7 +414,7 @@ static enum ast_rtp_glue_result gulp_get_vrtp_peer(struct ast_channel *chan, str ao2_ref(*instance, +1); ast_assert(endpoint != NULL); - if (endpoint->media_encryption != AST_SIP_MEDIA_ENCRYPT_NONE) { + if (endpoint->media.rtp.encryption != AST_SIP_MEDIA_ENCRYPT_NONE) { return AST_RTP_GLUE_RESULT_FORBID; } @@ -426,14 +426,15 @@ static void gulp_get_codec(struct ast_channel *chan, struct ast_format_cap *resu { struct ast_sip_channel_pvt *channel = ast_channel_tech_pvt(chan); - ast_format_cap_copy(result, channel->session->endpoint->codecs); + ast_format_cap_copy(result, channel->session->endpoint->media.codecs); } static int send_direct_media_request(void *data) { RAII_VAR(struct ast_sip_session *, session, data, ao2_cleanup); - return ast_sip_session_refresh(session, NULL, NULL, NULL, session->endpoint->direct_media_method, 1); + return ast_sip_session_refresh(session, NULL, NULL, NULL, + session->endpoint->media.direct_media.method, 1); } static struct ast_datastore_info direct_media_mitigation_info = { }; @@ -442,7 +443,7 @@ static int direct_media_mitigate_glare(struct ast_sip_session *session) { RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup); - if (session->endpoint->direct_media_glare_mitigation == + if (session->endpoint->media.direct_media.glare_mitigation == AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_NONE) { return 0; } @@ -455,10 +456,10 @@ static int direct_media_mitigate_glare(struct ast_sip_session *session) /* Removing the datastore ensures we won't try to mitigate glare on subsequent reinvites */ ast_sip_session_remove_datastore(session, "direct_media_glare_mitigation"); - if ((session->endpoint->direct_media_glare_mitigation == + if ((session->endpoint->media.direct_media.glare_mitigation == AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_OUTGOING && session->inv_session->role == PJSIP_ROLE_UAC) || - (session->endpoint->direct_media_glare_mitigation == + (session->endpoint->media.direct_media.glare_mitigation == AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_INCOMING && session->inv_session->role == PJSIP_ROLE_UAS)) { return 1; @@ -511,7 +512,7 @@ static int gulp_set_rtp_peer(struct ast_channel *chan, } ast_channel_cleanup(bridge_peer); - if (nat_active && session->endpoint->disable_direct_media_on_nat) { + if (nat_active && session->endpoint->media.direct_media.disable_on_nat) { return 0; } @@ -589,13 +590,13 @@ static struct ast_channel *gulp_new(struct ast_sip_session *session, int state, ast_rtp_instance_set_channel_id(pvt->media[SIP_MEDIA_VIDEO]->rtp, ast_channel_uniqueid(chan)); } - if (ast_format_cap_is_empty(session->req_caps) || !ast_format_cap_has_joint(session->req_caps, session->endpoint->codecs)) { - ast_format_cap_copy(ast_channel_nativeformats(chan), session->endpoint->codecs); + if (ast_format_cap_is_empty(session->req_caps) || !ast_format_cap_has_joint(session->req_caps, session->endpoint->media.codecs)) { + ast_format_cap_copy(ast_channel_nativeformats(chan), session->endpoint->media.codecs); } else { ast_format_cap_copy(ast_channel_nativeformats(chan), session->req_caps); } - ast_codec_choose(&session->endpoint->prefs, ast_channel_nativeformats(chan), 1, &fmt); + ast_codec_choose(&session->endpoint->media.prefs, ast_channel_nativeformats(chan), 1, &fmt); ast_format_copy(ast_channel_writeformat(chan), &fmt); ast_format_copy(ast_channel_rawwriteformat(chan), &fmt); ast_format_copy(ast_channel_readformat(chan), &fmt); @@ -611,11 +612,11 @@ static struct ast_channel *gulp_new(struct ast_sip_session *session, int state, ast_channel_exten_set(chan, S_OR(exten, "s")); ast_channel_priority_set(chan, 1); - ast_channel_callgroup_set(chan, session->endpoint->callgroup); - ast_channel_pickupgroup_set(chan, session->endpoint->pickupgroup); + ast_channel_callgroup_set(chan, session->endpoint->pickup.callgroup); + ast_channel_pickupgroup_set(chan, session->endpoint->pickup.pickupgroup); - ast_channel_named_callgroups_set(chan, session->endpoint->named_callgroups); - ast_channel_named_pickupgroups_set(chan, session->endpoint->named_pickupgroups); + ast_channel_named_callgroups_set(chan, session->endpoint->pickup.named_callgroups); + ast_channel_named_pickupgroups_set(chan, session->endpoint->pickup.named_pickupgroups); if (!ast_strlen_zero(session->endpoint->language)) { ast_channel_language_set(chan, session->endpoint->language); @@ -942,7 +943,7 @@ static int gulp_queryoption(struct ast_channel *ast, int option, void *data, int switch (option) { case AST_OPTION_T38_STATE: - if (session->endpoint->t38udptl) { + if (session->endpoint->media.t38.enabled) { switch (session->t38state) { case T38_LOCAL_REINVITE: case T38_PEER_REINVITE: @@ -1085,7 +1086,7 @@ static int update_connected_line_information(void *data) } } } else { - enum ast_sip_session_refresh_method method = session->endpoint->connected_line_method; + enum ast_sip_session_refresh_method method = session->endpoint->id.refresh_method; if (session->inv_session->invite_tsx && (session->inv_session->options & PJSIP_INV_SUPPORT_UPDATE)) { method = AST_SIP_SESSION_REFRESH_METHOD_UPDATE; @@ -1891,7 +1892,7 @@ static void gulp_session_begin(struct ast_sip_session *session) { RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup); - if (session->endpoint->direct_media_glare_mitigation == + if (session->endpoint->media.direct_media.glare_mitigation == AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_NONE) { return; } @@ -2007,7 +2008,7 @@ static void gulp_incoming_response(struct ast_sip_session *session, struct pjsip static int gulp_incoming_ack(struct ast_sip_session *session, struct pjsip_rx_data *rdata) { if (rdata->msg_info.msg->line.req.method.id == PJSIP_ACK_METHOD) { - if (session->endpoint->direct_media) { + if (session->endpoint->media.direct_media.enabled) { ast_queue_control(session->channel, AST_CONTROL_SRCCHANGE); } } diff --git a/include/asterisk/res_sip.h b/include/asterisk/res_sip.h index ed24f1e1b..23d1a641e 100644 --- a/include/asterisk/res_sip.h +++ b/include/asterisk/res_sip.h @@ -270,14 +270,19 @@ struct ast_sip_auth { enum ast_sip_auth_type type; }; +struct ast_sip_auth_array { + /*! Array of Sorcery IDs of auth sections */ + const char **names; + /*! Number of credentials in the array */ + unsigned int num; +}; + /*! * \brief Different methods by which incoming requests can be matched to endpoints */ enum ast_sip_endpoint_identifier_type { /*! Identify based on user name in From header */ AST_SIP_ENDPOINT_IDENTIFY_BY_USERNAME = (1 << 0), - /*! Identify based on source location of the SIP message */ - AST_SIP_ENDPOINT_IDENTIFY_BY_LOCATION = (1 << 1), }; enum ast_sip_session_refresh_method { @@ -312,118 +317,89 @@ enum ast_sip_session_media_encryption { }; /*! - * \brief An entity with which Asterisk communicates + * \brief Session timers options */ -struct ast_sip_endpoint { - SORCERY_OBJECT(details); +struct ast_sip_timer_options { + /*! Minimum session expiration period, in seconds */ + unsigned int min_se; + /*! Session expiration period, in seconds */ + unsigned int sess_expires; +}; + +/*! + * \brief Endpoint configuration for SIP extensions. + * + * SIP extensions, in this case refers to features + * indicated in Supported or Required headers. + */ +struct ast_sip_endpoint_extensions { + /*! Enabled SIP extensions */ + unsigned int flags; + /*! Timer options */ + struct ast_sip_timer_options timer; +}; + +/*! + * \brief Endpoint configuration for unsolicited MWI + */ +struct ast_sip_mwi_configuration { AST_DECLARE_STRING_FIELDS( - /*! Context to send incoming calls to */ - AST_STRING_FIELD(context); - /*! Name of an explicit transport to use */ - AST_STRING_FIELD(transport); - /*! Outbound proxy to use */ - AST_STRING_FIELD(outbound_proxy); - /*! Explicit AORs to dial if none are specified */ - AST_STRING_FIELD(aors); - /*! Musiconhold class to suggest that the other side use when placing on hold */ - AST_STRING_FIELD(mohsuggest); - /*! Optional external media address to use in SDP */ - AST_STRING_FIELD(external_media_address); /*! Configured voicemail boxes for this endpoint. Used for MWI */ AST_STRING_FIELD(mailboxes); - /*! Configured RTP engine for this endpoint. */ - AST_STRING_FIELD(rtp_engine); - /*! Configured tone zone for this endpoint. */ - AST_STRING_FIELD(zone); - /*! Configured language for this endpoint. */ - AST_STRING_FIELD(language); - /*! Feature to enact when one-touch recording INFO with Record: On is received */ - AST_STRING_FIELD(recordonfeature); - /*! Feature to enact when one-touch recording INFO with Record: Off is received */ - AST_STRING_FIELD(recordofffeature); - /*! SDP origin username */ - AST_STRING_FIELD(sdpowner); - /*! SDP session name */ - AST_STRING_FIELD(sdpsession); - /*! Default username to place in From header */ - AST_STRING_FIELD(fromuser); - /*! Domain to place in From header */ - AST_STRING_FIELD(fromdomain); /*! Username to use when sending MWI NOTIFYs to this endpoint */ - AST_STRING_FIELD(mwi_from); + AST_STRING_FIELD(fromuser); ); - /*! Identification information for this endpoint */ - struct ast_party_id id; - /*! Domain to which this endpoint belongs */ - struct ast_sip_domain *domain; - /*! Address of record for incoming registrations */ - struct ast_sip_aor *aor; - /*! Codec preferences */ - struct ast_codec_pref prefs; - /*! Configured codecs */ - struct ast_format_cap *codecs; - /*! Names of inbound authentication credentials */ - const char **sip_inbound_auths; - /*! Number of configured auths */ - size_t num_inbound_auths; - /*! Names of outbound authentication credentials */ - const char **sip_outbound_auths; - /*! Number of configured outbound auths */ - size_t num_outbound_auths; - /*! DTMF mode to use with this endpoint */ - enum ast_sip_dtmf_mode dtmf; - /*! Whether IPv6 RTP is enabled or not */ - unsigned int rtp_ipv6; - /*! Whether symmetric RTP is enabled or not */ - unsigned int rtp_symmetric; - /*! Whether ICE support is enabled or not */ - unsigned int ice_support; - /*! Whether to use the "ptime" attribute received from the endpoint or not */ - unsigned int use_ptime; + /* Should mailbox states be combined into a single notification? */ + unsigned int aggregate; +}; + +/*! + * \brief Endpoint subscription configuration + */ +struct ast_sip_endpoint_subscription_configuration { + /*! Indicates if endpoint is allowed to initiate subscriptions */ + unsigned int allow; + /*! The minimum allowed expiration for subscriptions from endpoint */ + unsigned int minexpiry; + /*! Message waiting configuration */ + struct ast_sip_mwi_configuration mwi; +}; + +/*! + * \brief NAT configuration options for endpoints + */ +struct ast_sip_endpoint_nat_configuration { /*! Whether to force using the source IP address/port for sending responses */ unsigned int force_rport; /*! Whether to rewrite the Contact header with the source IP address/port or not */ unsigned int rewrite_contact; - /*! Enabled SIP extensions */ - unsigned int extensions; - /*! Minimum session expiration period, in seconds */ - unsigned int min_se; - /*! Session expiration period, in seconds */ - unsigned int sess_expires; - /*! List of outbound registrations */ - AST_LIST_HEAD_NOLOCK(, ast_sip_registration) registrations; - /*! Method(s) by which the endpoint should be identified. */ - enum ast_sip_endpoint_identifier_type ident_method; - /*! Boolean indicating if direct_media is permissible */ - unsigned int direct_media; - /*! When using direct media, which method should be used */ - enum ast_sip_session_refresh_method direct_media_method; - /*! When performing connected line update, which method should be used */ - enum ast_sip_session_refresh_method connected_line_method; - /*! Take steps to mitigate glare for direct media */ - enum ast_sip_direct_media_glare_mitigation direct_media_glare_mitigation; - /*! Do not attempt direct media session refreshes if a media NAT is detected */ - unsigned int disable_direct_media_on_nat; - /*! Do we trust the endpoint with our outbound identity? */ - unsigned int trust_id_outbound; - /*! Do we trust identity information that originates externally (e.g. P-Asserted-Identity header)? */ - unsigned int trust_id_inbound; +}; + +/*! + * \brief Party identification options for endpoints + * + * This includes caller ID, connected line, and redirecting-related options + */ +struct ast_sip_endpoint_id_configuration { + struct ast_party_id self; + /*! Do we accept identification information from this endpoint */ + unsigned int trust_inbound; + /*! Do we send private identification information to this endpoint? */ + unsigned int trust_outbound; /*! Do we send P-Asserted-Identity headers to this endpoint? */ unsigned int send_pai; /*! Do we send Remote-Party-ID headers to this endpoint? */ unsigned int send_rpid; /*! Do we add Diversion headers to applicable outgoing requests/responses? */ unsigned int send_diversion; - /*! Should unsolicited MWI be aggregated into a single NOTIFY? */ - unsigned int aggregate_mwi; - /*! Do we use media encryption? what type? */ - enum ast_sip_session_media_encryption media_encryption; - /*! Do we use AVPF exclusively for this endpoint? */ - unsigned int use_avpf; - /*! Is one-touch recording permitted? */ - unsigned int one_touch_recording; - /*! Boolean indicating if ringing should be sent as inband progress */ - unsigned int inband_progress; + /*! When performing connected line update, which method should be used */ + enum ast_sip_session_refresh_method refresh_method; +}; + +/*! + * \brief Call pickup configuration options for endpoints + */ +struct ast_sip_endpoint_pickup_configuration { /*! Call group */ ast_group_t callgroup; /*! Pickup group */ @@ -432,24 +408,105 @@ struct ast_sip_endpoint { struct ast_namedgroups *named_callgroups; /*! Named pickup group */ struct ast_namedgroups *named_pickupgroups; - /*! Pointer to the persistent Asterisk endpoint */ - struct ast_endpoint *persistent; - /*! The number of channels at which busy device state is returned */ - unsigned int devicestate_busy_at; +}; + +/*! + * \brief Configuration for one-touch INFO recording + */ +struct ast_sip_info_recording_configuration { + AST_DECLARE_STRING_FIELDS( + /*! Feature to enact when one-touch recording INFO with Record: On is received */ + AST_STRING_FIELD(onfeature); + /*! Feature to enact when one-touch recording INFO with Record: Off is received */ + AST_STRING_FIELD(offfeature); + ); + /*! Is one-touch recording permitted? */ + unsigned int enabled; +}; + +/*! + * \brief Endpoint configuration options for INFO packages + */ +struct ast_sip_endpoint_info_configuration { + /*! Configuration for one-touch recording */ + struct ast_sip_info_recording_configuration recording; +}; + +/*! + * \brief RTP configuration for SIP endpoints + */ +struct ast_sip_media_rtp_configuration { + AST_DECLARE_STRING_FIELDS( + /*! Configured RTP engine for this endpoint. */ + AST_STRING_FIELD(engine); + ); + /*! Whether IPv6 RTP is enabled or not */ + unsigned int ipv6; + /*! Whether symmetric RTP is enabled or not */ + unsigned int symmetric; + /*! Whether ICE support is enabled or not */ + unsigned int ice_support; + /*! Whether to use the "ptime" attribute received from the endpoint or not */ + unsigned int use_ptime; + /*! Do we use AVPF exclusively for this endpoint? */ + unsigned int use_avpf; + /*! \brief DTLS-SRTP configuration information */ + struct ast_rtp_dtls_cfg dtls_cfg; + /*! Should SRTP use a 32 byte tag instead of an 80 byte tag? */ + unsigned int srtp_tag_32; + /*! Do we use media encryption? what type? */ + enum ast_sip_session_media_encryption encryption; +}; + +/*! + * \brief Direct media options for SIP endpoints + */ +struct ast_sip_direct_media_configuration { + /*! Boolean indicating if direct_media is permissible */ + unsigned int enabled; + /*! When using direct media, which method should be used */ + enum ast_sip_session_refresh_method method; + /*! Take steps to mitigate glare for direct media */ + enum ast_sip_direct_media_glare_mitigation glare_mitigation; + /*! Do not attempt direct media session refreshes if a media NAT is detected */ + unsigned int disable_on_nat; +}; + +struct ast_sip_t38_configuration { /*! Whether T.38 UDPTL support is enabled or not */ - unsigned int t38udptl; + unsigned int enabled; /*! Error correction setting for T.38 UDPTL */ - enum ast_t38_ec_modes t38udptl_ec; + enum ast_t38_ec_modes error_correction; /*! Explicit T.38 max datagram value, may be 0 to indicate the remote side can be trusted */ - unsigned int t38udptl_maxdatagram; - /*! Whether fax detection is enabled or not (CNG tone detection) */ - unsigned int faxdetect; + unsigned int maxdatagram; /*! Whether NAT Support is enabled for T.38 UDPTL sessions or not */ - unsigned int t38udptl_nat; + unsigned int nat; /*! Whether to use IPv6 for UDPTL or not */ - unsigned int t38udptl_ipv6; - /*! Determines if transfers (using REFER) are allowed by this endpoint */ - unsigned int allowtransfer; + unsigned int ipv6; +}; + +/*! + * \brief Media configuration for SIP endpoints + */ +struct ast_sip_endpoint_media_configuration { + AST_DECLARE_STRING_FIELDS( + /*! Optional external media address to use in SDP */ + AST_STRING_FIELD(external_address); + /*! SDP origin username */ + AST_STRING_FIELD(sdpowner); + /*! SDP session name */ + AST_STRING_FIELD(sdpsession); + ); + /*! RTP media configuration */ + struct ast_sip_media_rtp_configuration rtp; + /*! Direct media options */ + struct ast_sip_direct_media_configuration direct_media; + /*! T.38 (FoIP) options */ + struct ast_sip_t38_configuration t38; + /*! Codec preferences */ + struct ast_codec_pref prefs; + /*! Configured codecs */ + struct ast_format_cap *codecs; /*! DSCP TOS bits for audio streams */ unsigned int tos_audio; /*! Priority for audio streams */ @@ -458,16 +515,84 @@ struct ast_sip_endpoint { unsigned int tos_video; /*! Priority for video streams */ unsigned int cos_video; - /*! Indicates if endpoint is allowed to initiate subscriptions */ - unsigned int allowsubscribe; - /*! The minimum allowed expiration for subscriptions from endpoint */ - unsigned int subminexpiry; - /*! \brief DTLS-SRTP configuration information */ - struct ast_rtp_dtls_cfg dtls_cfg; - /*! Should SRTP use a 32 byte tag instead of an 80 byte tag? */ - unsigned int srtp_tag_32; }; +/*! + * \brief An entity with which Asterisk communicates + */ +struct ast_sip_endpoint { + SORCERY_OBJECT(details); + AST_DECLARE_STRING_FIELDS( + /*! Context to send incoming calls to */ + AST_STRING_FIELD(context); + /*! Name of an explicit transport to use */ + AST_STRING_FIELD(transport); + /*! Outbound proxy to use */ + AST_STRING_FIELD(outbound_proxy); + /*! Explicit AORs to dial if none are specified */ + AST_STRING_FIELD(aors); + /*! Musiconhold class to suggest that the other side use when placing on hold */ + AST_STRING_FIELD(mohsuggest); + /*! Configured tone zone for this endpoint. */ + AST_STRING_FIELD(zone); + /*! Configured language for this endpoint. */ + AST_STRING_FIELD(language); + /*! Default username to place in From header */ + AST_STRING_FIELD(fromuser); + /*! Domain to place in From header */ + AST_STRING_FIELD(fromdomain); + ); + /*! Configuration for extensions */ + struct ast_sip_endpoint_extensions extensions; + /*! Configuration relating to media */ + struct ast_sip_endpoint_media_configuration media; + /*! SUBSCRIBE/NOTIFY configuration options */ + struct ast_sip_endpoint_subscription_configuration subscription; + /*! NAT configuration */ + struct ast_sip_endpoint_nat_configuration nat; + /*! Party identification options */ + struct ast_sip_endpoint_id_configuration id; + /*! Configuration options for INFO packages */ + struct ast_sip_endpoint_info_configuration info; + /*! Call pickup configuration */ + struct ast_sip_endpoint_pickup_configuration pickup; + /*! Inbound authentication credentials */ + struct ast_sip_auth_array inbound_auths; + /*! Outbound authentication credentials */ + struct ast_sip_auth_array outbound_auths; + /*! DTMF mode to use with this endpoint */ + enum ast_sip_dtmf_mode dtmf; + /*! Method(s) by which the endpoint should be identified. */ + enum ast_sip_endpoint_identifier_type ident_method; + /*! Boolean indicating if ringing should be sent as inband progress */ + unsigned int inband_progress; + /*! Pointer to the persistent Asterisk endpoint */ + struct ast_endpoint *persistent; + /*! The number of channels at which busy device state is returned */ + unsigned int devicestate_busy_at; + /*! Whether fax detection is enabled or not (CNG tone detection) */ + unsigned int faxdetect; + /*! Determines if transfers (using REFER) are allowed by this endpoint */ + unsigned int allowtransfer; +}; + +/*! + * \brief Initialize an auth array with the configured values. + * + * \param array Array to initialize + * \param auth_names Comma-separated list of names to set in the array + * \retval 0 Success + * \retval non-zero Failure + */ +int ast_sip_auth_array_init(struct ast_sip_auth_array *array, const char *auth_names); + +/*! + * \brief Free contents of an auth array. + * + * \param array Array whose contents are to be freed + */ +void ast_sip_auth_array_destroy(struct ast_sip_auth_array *array); + /*! * \brief Possible returns from ast_sip_check_authentication */ @@ -519,14 +644,13 @@ struct ast_sip_outbound_authenticator { * \brief Create a new request with authentication credentials * * \param auths An array of IDs of auth sorcery objects - * \param num_auths The number of IDs in the array * \param challenge The SIP response with authentication challenge(s) * \param tsx The transaction in which the challenge was received * \param new_request The new SIP request with challenge response(s) * \retval 0 Successfully created new request * \retval -1 Failed to create a new request */ - int (*create_request_with_auth)(const char **auths, size_t num_auths, struct pjsip_rx_data *challenge, + int (*create_request_with_auth)(const struct ast_sip_auth_array *auths, struct pjsip_rx_data *challenge, struct pjsip_transaction *tsx, struct pjsip_tx_data **new_request); }; @@ -1183,7 +1307,7 @@ enum ast_sip_check_auth_result ast_sip_check_authentication(struct ast_sip_endpo * callback in the \ref ast_sip_outbound_authenticator structure for details about * the parameters and return values. */ -int ast_sip_create_request_with_auth(const char **auths, size_t num_auths, pjsip_rx_data *challenge, +int ast_sip_create_request_with_auth(const struct ast_sip_auth_array *auths, pjsip_rx_data *challenge, pjsip_transaction *tsx, pjsip_tx_data **new_request); /*! @@ -1294,11 +1418,10 @@ struct ao2_container *ast_sip_get_endpoints(void); /*! * \brief Retrieve relevant SIP auth structures from sorcery * - * \param auth_names The sorcery IDs of auths to retrieve - * \param num_auths The number of auths to retrieve + * \param auths Array of sorcery IDs of auth credentials to retrieve * \param[out] out The retrieved auths are stored here */ -int ast_sip_retrieve_auths(const char *auth_names[], size_t num_auths, struct ast_sip_auth **out); +int ast_sip_retrieve_auths(const struct ast_sip_auth_array *auths, struct ast_sip_auth **out); /*! * \brief Clean up retrieved auth structures from memory diff --git a/res/res_sip.c b/res/res_sip.c index 57c1bed17..06be279c1 100644 --- a/res/res_sip.c +++ b/res/res_sip.c @@ -1068,14 +1068,14 @@ void ast_sip_unregister_outbound_authenticator(struct ast_sip_outbound_authentic ast_module_unref(ast_module_info->self); } -int ast_sip_create_request_with_auth(const char **auths, size_t num_auths, pjsip_rx_data *challenge, +int ast_sip_create_request_with_auth(const struct ast_sip_auth_array *auths, pjsip_rx_data *challenge, pjsip_transaction *tsx, pjsip_tx_data **new_request) { if (!registered_outbound_authenticator) { ast_log(LOG_WARNING, "No SIP outbound authenticator registered. Cannot respond to authentication challenge\n"); return -1; } - return registered_outbound_authenticator->create_request_with_auth(auths, num_auths, challenge, tsx, new_request); + return registered_outbound_authenticator->create_request_with_auth(auths, challenge, tsx, new_request); } struct endpoint_identifier_list { @@ -1475,7 +1475,7 @@ static void send_request_cb(void *token, pjsip_event *e) return; } - if (!ast_sip_create_request_with_auth(endpoint->sip_outbound_auths, endpoint->num_outbound_auths, challenge, tsx, &tdata)) { + if (!ast_sip_create_request_with_auth(&endpoint->outbound_auths, challenge, tsx, &tdata)) { pjsip_endpt_send_request(ast_sip_get_pjsip_endpoint(), tdata, -1, NULL, NULL); } } diff --git a/res/res_sip.exports.in b/res/res_sip.exports.in index 3557fd6ef..f3b4f0eec 100644 --- a/res/res_sip.exports.in +++ b/res/res_sip.exports.in @@ -65,6 +65,8 @@ LINKER_SYMBOL_PREFIXast_sip_add_global_request_header; LINKER_SYMBOL_PREFIXast_sip_add_global_response_header; LINKER_SYMBOL_PREFIXast_sip_initialize_sorcery_global; + LINKER_SYMBOL_PREFIXast_sip_auth_array_init; + LINKER_SYMBOL_PREFIXast_sip_auth_array_destroy; local: *; }; diff --git a/res/res_sip/sip_configuration.c b/res/res_sip/sip_configuration.c index cb8dc9fd8..0fb433b58 100644 --- a/res/res_sip/sip_configuration.c +++ b/res/res_sip/sip_configuration.c @@ -247,11 +247,11 @@ static int prack_handler(const struct aco_option *opt, struct ast_variable *var, struct ast_sip_endpoint *endpoint = obj; if (ast_true(var->value)) { - endpoint->extensions |= PJSIP_INV_SUPPORT_100REL; + endpoint->extensions.flags |= PJSIP_INV_SUPPORT_100REL; } else if (ast_false(var->value)) { - endpoint->extensions &= PJSIP_INV_SUPPORT_100REL; + endpoint->extensions.flags &= PJSIP_INV_SUPPORT_100REL; } else if (!strcasecmp(var->value, "required")) { - endpoint->extensions |= PJSIP_INV_REQUIRE_100REL; + endpoint->extensions.flags |= PJSIP_INV_REQUIRE_100REL; } else { return -1; } @@ -264,13 +264,13 @@ static int timers_handler(const struct aco_option *opt, struct ast_variable *var struct ast_sip_endpoint *endpoint = obj; if (ast_true(var->value)) { - endpoint->extensions |= PJSIP_INV_SUPPORT_TIMER; + endpoint->extensions.flags |= PJSIP_INV_SUPPORT_TIMER; } else if (ast_false(var->value)) { - endpoint->extensions &= PJSIP_INV_SUPPORT_TIMER; + endpoint->extensions.flags &= PJSIP_INV_SUPPORT_TIMER; } else if (!strcasecmp(var->value, "required")) { - endpoint->extensions |= PJSIP_INV_REQUIRE_TIMER; + endpoint->extensions.flags |= PJSIP_INV_REQUIRE_TIMER; } else if (!strcasecmp(var->value, "always")) { - endpoint->extensions |= PJSIP_INV_ALWAYS_USE_TIMER; + endpoint->extensions.flags |= PJSIP_INV_ALWAYS_USE_TIMER; } else { return -1; } @@ -278,7 +278,7 @@ static int timers_handler(const struct aco_option *opt, struct ast_variable *var return 0; } -static void destroy_auths(const char **auths, size_t num_auths) +void ast_sip_auth_array_destroy(struct ast_sip_auth_array *auths) { int i; @@ -286,63 +286,57 @@ static void destroy_auths(const char **auths, size_t num_auths) return; } - for (i = 0; i < num_auths; ++i) { - ast_free((char *) auths[i]); + for (i = 0; i < auths->num; ++i) { + ast_free((char *) auths->names[i]); } - ast_free(auths); + ast_free(auths->names); + auths->num = 0; } #define AUTH_INCREMENT 4 -static const char **auth_alloc(const char *value, size_t *num_auths) +int ast_sip_auth_array_init(struct ast_sip_auth_array *auths, const char *value) { - char *auths = ast_strdupa(value); + char *auth_names = ast_strdupa(value); char *val; int num_alloced = 0; const char **alloced_auths = NULL; - while ((val = strsep(&auths, ","))) { - if (*num_auths >= num_alloced) { + while ((val = strsep(&auth_names, ","))) { + if (auths->num >= num_alloced) { size_t size; num_alloced += AUTH_INCREMENT; size = num_alloced * sizeof(char *); - alloced_auths = ast_realloc(alloced_auths, size); - if (!alloced_auths) { + auths->names = ast_realloc(alloced_auths, size); + if (!auths->names) { goto failure; } } - alloced_auths[*num_auths] = ast_strdup(val); - if (!alloced_auths[*num_auths]) { + auths->names[auths->num] = ast_strdup(val); + if (!auths->names[auths->num]) { goto failure; } - ++(*num_auths); + ++auths->num; } - return alloced_auths; + return 0; failure: - destroy_auths(alloced_auths, *num_auths); - return NULL; + ast_sip_auth_array_destroy(auths); + return -1; } static int inbound_auth_handler(const struct aco_option *opt, struct ast_variable *var, void *obj) { struct ast_sip_endpoint *endpoint = obj; - endpoint->sip_inbound_auths = auth_alloc(var->value, &endpoint->num_inbound_auths); - if (!endpoint->sip_inbound_auths) { - return -1; - } - return 0; + return ast_sip_auth_array_init(&endpoint->inbound_auths, var->value); } + static int outbound_auth_handler(const struct aco_option *opt, struct ast_variable *var, void *obj) { struct ast_sip_endpoint *endpoint = obj; - endpoint->sip_outbound_auths = auth_alloc(var->value, &endpoint->num_outbound_auths); - if (!endpoint->sip_outbound_auths) { - return -1; - } - return 0; + return ast_sip_auth_array_init(&endpoint->outbound_auths, var->value); } static int ident_handler(const struct aco_option *opt, struct ast_variable *var, void *obj) @@ -354,8 +348,6 @@ static int ident_handler(const struct aco_option *opt, struct ast_variable *var, while ((val = strsep(&idents, ","))) { if (!strcasecmp(val, "username")) { endpoint->ident_method |= AST_SIP_ENDPOINT_IDENTIFY_BY_USERNAME; - } else if (!strcasecmp(val, "location")) { - endpoint->ident_method |= AST_SIP_ENDPOINT_IDENTIFY_BY_LOCATION; } else { ast_log(LOG_ERROR, "Unrecognized identification method %s specified for endpoint %s\n", val, ast_sorcery_object_get_id(endpoint)); @@ -370,9 +362,9 @@ static int direct_media_method_handler(const struct aco_option *opt, struct ast_ struct ast_sip_endpoint *endpoint = obj; if (!strcasecmp(var->value, "invite") || !strcasecmp(var->value, "reinvite")) { - endpoint->direct_media_method = AST_SIP_SESSION_REFRESH_METHOD_INVITE; + endpoint->media.direct_media.method = AST_SIP_SESSION_REFRESH_METHOD_INVITE; } else if (!strcasecmp(var->value, "update")) { - endpoint->direct_media_method = AST_SIP_SESSION_REFRESH_METHOD_UPDATE; + endpoint->media.direct_media.method = AST_SIP_SESSION_REFRESH_METHOD_UPDATE; } else { ast_log(LOG_NOTICE, "Unrecognized option value %s for %s on endpoint %s\n", var->value, var->name, ast_sorcery_object_get_id(endpoint)); @@ -386,9 +378,9 @@ static int connected_line_method_handler(const struct aco_option *opt, struct as struct ast_sip_endpoint *endpoint = obj; if (!strcasecmp(var->value, "invite") || !strcasecmp(var->value, "reinvite")) { - endpoint->connected_line_method = AST_SIP_SESSION_REFRESH_METHOD_INVITE; + endpoint->id.refresh_method = AST_SIP_SESSION_REFRESH_METHOD_INVITE; } else if (!strcasecmp(var->value, "update")) { - endpoint->connected_line_method = AST_SIP_SESSION_REFRESH_METHOD_UPDATE; + endpoint->id.refresh_method = AST_SIP_SESSION_REFRESH_METHOD_UPDATE; } else { ast_log(LOG_NOTICE, "Unrecognized option value %s for %s on endpoint %s\n", var->value, var->name, ast_sorcery_object_get_id(endpoint)); @@ -402,11 +394,11 @@ static int direct_media_glare_mitigation_handler(const struct aco_option *opt, s struct ast_sip_endpoint *endpoint = obj; if (!strcasecmp(var->value, "none")) { - endpoint->direct_media_glare_mitigation = AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_NONE; + endpoint->media.direct_media.glare_mitigation = AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_NONE; } else if (!strcasecmp(var->value, "outgoing")) { - endpoint->direct_media_glare_mitigation = AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_OUTGOING; + endpoint->media.direct_media.glare_mitigation = AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_OUTGOING; } else if (!strcasecmp(var->value, "incoming")) { - endpoint->direct_media_glare_mitigation = AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_INCOMING; + endpoint->media.direct_media.glare_mitigation = AST_SIP_DIRECT_MEDIA_GLARE_MITIGATION_INCOMING; } else { ast_log(LOG_NOTICE, "Unrecognized option value %s for %s on endpoint %s\n", var->value, var->name, ast_sorcery_object_get_id(endpoint)); @@ -424,18 +416,18 @@ static int caller_id_handler(const struct aco_option *opt, struct ast_variable * ast_callerid_split(var->value, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num)); if (!ast_strlen_zero(cid_name)) { - endpoint->id.name.str = ast_strdup(cid_name); - if (!endpoint->id.name.str) { + endpoint->id.self.name.str = ast_strdup(cid_name); + if (!endpoint->id.self.name.str) { return -1; } - endpoint->id.name.valid = 1; + endpoint->id.self.name.valid = 1; } if (!ast_strlen_zero(cid_num)) { - endpoint->id.number.str = ast_strdup(cid_num); - if (!endpoint->id.number.str) { + endpoint->id.self.number.str = ast_strdup(cid_num); + if (!endpoint->id.self.number.str) { return -1; } - endpoint->id.number.valid = 1; + endpoint->id.self.number.valid = 1; } return 0; } @@ -447,16 +439,16 @@ static int caller_id_privacy_handler(const struct aco_option *opt, struct ast_va if (callingpres == -1 && sscanf(var->value, "%d", &callingpres) != 1) { return -1; } - endpoint->id.number.presentation = callingpres; - endpoint->id.name.presentation = callingpres; + endpoint->id.self.number.presentation = callingpres; + endpoint->id.self.name.presentation = callingpres; return 0; } static int caller_id_tag_handler(const struct aco_option *opt, struct ast_variable *var, void *obj) { struct ast_sip_endpoint *endpoint = obj; - endpoint->id.tag = ast_strdup(var->value); - return endpoint->id.tag ? 0 : -1; + endpoint->id.self.tag = ast_strdup(var->value); + return endpoint->id.self.tag ? 0 : -1; } static int media_encryption_handler(const struct aco_option *opt, struct ast_variable *var, void *obj) @@ -464,12 +456,12 @@ static int media_encryption_handler(const struct aco_option *opt, struct ast_var struct ast_sip_endpoint *endpoint = obj; if (!strcasecmp("no", var->value)) { - endpoint->media_encryption = AST_SIP_MEDIA_ENCRYPT_NONE; + endpoint->media.rtp.encryption = AST_SIP_MEDIA_ENCRYPT_NONE; } else if (!strcasecmp("sdes", var->value)) { - endpoint->media_encryption = AST_SIP_MEDIA_ENCRYPT_SDES; + endpoint->media.rtp.encryption = AST_SIP_MEDIA_ENCRYPT_SDES; } else if (!strcasecmp("dtls", var->value)) { - endpoint->media_encryption = AST_SIP_MEDIA_ENCRYPT_DTLS; - ast_rtp_dtls_cfg_parse(&endpoint->dtls_cfg, "dtlsenable", "yes"); + endpoint->media.rtp.encryption = AST_SIP_MEDIA_ENCRYPT_DTLS; + ast_rtp_dtls_cfg_parse(&endpoint->media.rtp.dtls_cfg, "dtlsenable", "yes"); } else { return -1; } @@ -483,11 +475,11 @@ static int group_handler(const struct aco_option *opt, struct ast_sip_endpoint *endpoint = obj; if (!strncmp(var->name, "callgroup", 9)) { - if (!(endpoint->callgroup = ast_get_group(var->value))) { + if (!(endpoint->pickup.callgroup = ast_get_group(var->value))) { return -1; } } else if (!strncmp(var->name, "pickupgroup", 11)) { - if (!(endpoint->pickupgroup = ast_get_group(var->value))) { + if (!(endpoint->pickup.pickupgroup = ast_get_group(var->value))) { return -1; } } else { @@ -503,12 +495,12 @@ static int named_groups_handler(const struct aco_option *opt, struct ast_sip_endpoint *endpoint = obj; if (!strncmp(var->name, "namedcallgroup", 14)) { - if (!(endpoint->named_callgroups = + if (!(endpoint->pickup.named_callgroups = ast_get_namedgroups(var->value))) { return -1; } } else if (!strncmp(var->name, "namedpickupgroup", 16)) { - if (!(endpoint->named_pickupgroups = + if (!(endpoint->pickup.named_pickupgroups = ast_get_namedgroups(var->value))) { return -1; } @@ -524,7 +516,7 @@ static int dtls_handler(const struct aco_option *opt, { struct ast_sip_endpoint *endpoint = obj; - return ast_rtp_dtls_cfg_parse(&endpoint->dtls_cfg, var->name, var->value); + return ast_rtp_dtls_cfg_parse(&endpoint->media.rtp.dtls_cfg, var->name, var->value); } static int t38udptl_ec_handler(const struct aco_option *opt, @@ -533,11 +525,11 @@ static int t38udptl_ec_handler(const struct aco_option *opt, struct ast_sip_endpoint *endpoint = obj; if (!strcmp(var->value, "none")) { - endpoint->t38udptl_ec = UDPTL_ERROR_CORRECTION_NONE; + endpoint->media.t38.error_correction = UDPTL_ERROR_CORRECTION_NONE; } else if (!strcmp(var->value, "fec")) { - endpoint->t38udptl_ec = UDPTL_ERROR_CORRECTION_FEC; + endpoint->media.t38.error_correction = UDPTL_ERROR_CORRECTION_FEC; } else if (!strcmp(var->value, "redundancy")) { - endpoint->t38udptl_ec = UDPTL_ERROR_CORRECTION_REDUNDANCY; + endpoint->media.t38.error_correction = UDPTL_ERROR_CORRECTION_REDUNDANCY; } else { return -1; } @@ -640,75 +632,74 @@ int ast_res_sip_initialize_configuration(void) ast_sorcery_object_field_register(sip_sorcery, "endpoint", "type", "", OPT_NOOP_T, 0, 0); ast_sorcery_object_field_register(sip_sorcery, "endpoint", "context", "default", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, context)); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "disallow", "", OPT_CODEC_T, 0, FLDSET(struct ast_sip_endpoint, prefs, codecs)); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "allow", "", OPT_CODEC_T, 1, FLDSET(struct ast_sip_endpoint, prefs, codecs)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "disallow", "", OPT_CODEC_T, 0, FLDSET(struct ast_sip_endpoint, media.prefs, media.codecs)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "allow", "", OPT_CODEC_T, 1, FLDSET(struct ast_sip_endpoint, media.prefs, media.codecs)); ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "dtmfmode", "rfc4733", dtmf_handler, NULL, 0, 0); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "rtp_ipv6", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, rtp_ipv6)); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "rtp_symmetric", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, rtp_symmetric)); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "ice_support", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, ice_support)); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "use_ptime", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, use_ptime)); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "force_rport", "yes", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, force_rport)); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "rewrite_contact", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, rewrite_contact)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "rtp_ipv6", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, media.rtp.ipv6)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "rtp_symmetric", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, media.rtp.symmetric)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "ice_support", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, media.rtp.ice_support)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "use_ptime", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, media.rtp.use_ptime)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "force_rport", "yes", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, nat.force_rport)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "rewrite_contact", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, nat.rewrite_contact)); ast_sorcery_object_field_register(sip_sorcery, "endpoint", "transport", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, transport)); ast_sorcery_object_field_register(sip_sorcery, "endpoint", "outbound_proxy", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, outbound_proxy)); ast_sorcery_object_field_register(sip_sorcery, "endpoint", "mohsuggest", "default", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, mohsuggest)); ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "100rel", "yes", prack_handler, NULL, 0, 0); ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "timers", "yes", timers_handler, NULL, 0, 0); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "timers_min_se", "90", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, min_se)); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "timers_sess_expires", "1800", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, sess_expires)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "timers_min_se", "90", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, extensions.timer.min_se)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "timers_sess_expires", "1800", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, extensions.timer.sess_expires)); ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "auth", "", inbound_auth_handler, NULL, 0, 0); ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "outbound_auth", "", outbound_auth_handler, NULL, 0, 0); ast_sorcery_object_field_register(sip_sorcery, "endpoint", "aors", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, aors)); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "external_media_address", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, external_media_address)); - ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "identify_by", "username,location", ident_handler, NULL, 0, 0); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "direct_media", "yes", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, direct_media)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "external_media_address", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, media.external_address)); + ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "identify_by", "username", ident_handler, NULL, 0, 0); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "direct_media", "yes", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, media.direct_media.enabled)); ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "direct_media_method", "invite", direct_media_method_handler, NULL, 0, 0); ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "connected_line_method", "invite", connected_line_method_handler, NULL, 0, 0); ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "direct_media_glare_mitigation", "none", direct_media_glare_mitigation_handler, NULL, 0, 0); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "disable_direct_media_on_nat", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, disable_direct_media_on_nat)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "disable_direct_media_on_nat", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, media.direct_media.disable_on_nat)); ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "callerid", "", caller_id_handler, NULL, 0, 0); ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "callerid_privacy", "", caller_id_privacy_handler, NULL, 0, 0); ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "callerid_tag", "", caller_id_tag_handler, NULL, 0, 0); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "trust_id_inbound", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, trust_id_inbound)); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "trust_id_outbound", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, trust_id_outbound)); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "send_pai", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, send_pai)); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "send_rpid", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, send_rpid)); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "send_diversion", "yes", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, send_diversion)); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "mailboxes", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, mailboxes)); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "aggregate_mwi", "yes", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, aggregate_mwi)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "trust_id_inbound", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, id.trust_inbound)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "trust_id_outbound", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, id.trust_outbound)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "send_pai", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, id.send_pai)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "send_rpid", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, id.send_rpid)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "send_diversion", "yes", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, id.send_diversion)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "mailboxes", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, subscription.mwi.mailboxes)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "aggregate_mwi", "yes", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, subscription.mwi.aggregate)); ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "media_encryption", "no", media_encryption_handler, NULL, 0, 0); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "use_avpf", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, use_avpf)); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "one_touch_recording", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, one_touch_recording)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "use_avpf", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, media.rtp.use_avpf)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "one_touch_recording", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, info.recording.enabled)); ast_sorcery_object_field_register(sip_sorcery, "endpoint", "inband_progress", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, inband_progress)); ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "callgroup", "", group_handler, NULL, 0, 0); ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "pickupgroup", "", group_handler, NULL, 0, 0); ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "namedcallgroup", "", named_groups_handler, NULL, 0, 0); ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "namedpickupgroup", "", named_groups_handler, NULL, 0, 0); ast_sorcery_object_field_register(sip_sorcery, "endpoint", "devicestate_busy_at", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, devicestate_busy_at)); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "t38udptl", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, t38udptl)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "t38udptl", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, media.t38.enabled)); ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "t38udptl_ec", "none", t38udptl_ec_handler, NULL, 0, 0); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "t38udptl_maxdatagram", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, t38udptl_maxdatagram)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "t38udptl_maxdatagram", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, media.t38.maxdatagram)); ast_sorcery_object_field_register(sip_sorcery, "endpoint", "faxdetect", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, faxdetect)); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "t38udptl_nat", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, t38udptl_nat)); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "t38udptl_ipv6", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, t38udptl_ipv6)); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "rtpengine", "asterisk", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, rtp_engine)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "t38udptl_nat", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, media.t38.nat)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "t38udptl_ipv6", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, media.t38.ipv6)); ast_sorcery_object_field_register(sip_sorcery, "endpoint", "tonezone", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, zone)); ast_sorcery_object_field_register(sip_sorcery, "endpoint", "language", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, language)); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "recordonfeature", "automixmon", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, recordonfeature)); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "recordofffeature", "automixmon", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, recordofffeature)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "recordonfeature", "automixmon", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, info.recording.onfeature)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "recordofffeature", "automixmon", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, info.recording.offfeature)); ast_sorcery_object_field_register(sip_sorcery, "endpoint", "allowtransfer", "yes", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, allowtransfer)); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "sdpowner", "-", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, sdpowner)); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "sdpsession", "Asterisk", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, sdpsession)); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "tos_audio", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, tos_audio)); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "tos_video", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, tos_video)); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "cos_audio", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, cos_audio)); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "cos_video", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, cos_video)); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "allowsubscribe", "yes", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, allowsubscribe)); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "subminexpiry", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, subminexpiry)); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "subminexpirey", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, subminexpiry)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "sdpowner", "-", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, media.sdpowner)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "sdpsession", "Asterisk", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, media.sdpsession)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "tos_audio", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, media.tos_audio)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "tos_video", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, media.tos_video)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "cos_audio", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, media.cos_audio)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "cos_video", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, media.cos_video)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "allowsubscribe", "yes", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, subscription.allow)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "subminexpiry", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, subscription.minexpiry)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "subminexpirey", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, subscription.minexpiry)); ast_sorcery_object_field_register(sip_sorcery, "endpoint", "fromuser", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, fromuser)); ast_sorcery_object_field_register(sip_sorcery, "endpoint", "fromdomain", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, fromdomain)); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "mwifromuser", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, mwi_from)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "mwifromuser", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_endpoint, subscription.mwi.fromuser)); ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "dtlsverify", "", dtls_handler, NULL, 0, 0); ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "dtlsrekey", "", dtls_handler, NULL, 0, 0); ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "dtlscertfile", "", dtls_handler, NULL, 0, 0); @@ -717,7 +708,7 @@ int ast_res_sip_initialize_configuration(void) ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "dtlscafile", "", dtls_handler, NULL, 0, 0); ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "dtlscapath", "", dtls_handler, NULL, 0, 0); ast_sorcery_object_field_register_custom(sip_sorcery, "endpoint", "dtlssetup", "", dtls_handler, NULL, 0, 0); - ast_sorcery_object_field_register(sip_sorcery, "endpoint", "srtp_tag_32", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, srtp_tag_32)); + ast_sorcery_object_field_register(sip_sorcery, "endpoint", "srtp_tag_32", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, media.rtp.srtp_tag_32)); if (ast_sip_initialize_sorcery_transport(sip_sorcery)) { ast_log(LOG_ERROR, "Failed to register SIP transport support with sorcery\n"); @@ -782,23 +773,57 @@ int ast_res_sip_reload_configuration(void) return 0; } +static void subscription_configuration_destroy(struct ast_sip_endpoint_subscription_configuration *subscription) +{ + ast_string_field_free_memory(&subscription->mwi); +} + +static void info_configuration_destroy(struct ast_sip_endpoint_info_configuration *info) +{ + ast_string_field_free_memory(&info->recording); +} + +static void media_configuration_destroy(struct ast_sip_endpoint_media_configuration *media) +{ + ast_string_field_free_memory(&media->rtp); + ast_string_field_free_memory(media); +} + static void endpoint_destructor(void* obj) { struct ast_sip_endpoint *endpoint = obj; ast_string_field_free_memory(endpoint); - if (endpoint->codecs) { - ast_format_cap_destroy(endpoint->codecs); - } - destroy_auths(endpoint->sip_inbound_auths, endpoint->num_inbound_auths); - destroy_auths(endpoint->sip_outbound_auths, endpoint->num_outbound_auths); - ast_party_id_free(&endpoint->id); - endpoint->named_callgroups = ast_unref_namedgroups(endpoint->named_callgroups); - endpoint->named_pickupgroups = ast_unref_namedgroups(endpoint->named_pickupgroups); + if (endpoint->media.codecs) { + ast_format_cap_destroy(endpoint->media.codecs); + } + subscription_configuration_destroy(&endpoint->subscription); + info_configuration_destroy(&endpoint->info); + media_configuration_destroy(&endpoint->media); + ast_sip_auth_array_destroy(&endpoint->inbound_auths); + ast_sip_auth_array_destroy(&endpoint->outbound_auths); + ast_party_id_free(&endpoint->id.self); + endpoint->pickup.named_callgroups = ast_unref_namedgroups(endpoint->pickup.named_callgroups); + endpoint->pickup.named_pickupgroups = ast_unref_namedgroups(endpoint->pickup.named_pickupgroups); ao2_cleanup(endpoint->persistent); } +static int init_subscription_configuration(struct ast_sip_endpoint_subscription_configuration *subscription) +{ + return ast_string_field_init(&subscription->mwi, 64); +} + +static int init_info_configuration(struct ast_sip_endpoint_info_configuration *info) +{ + return ast_string_field_init(&info->recording, 32); +} + +static int init_media_configuration(struct ast_sip_endpoint_media_configuration *media) +{ + return ast_string_field_init(media, 64) || ast_string_field_init(&media->rtp, 32); +} + void *ast_sip_endpoint_alloc(const char *name) { struct ast_sip_endpoint *endpoint = ast_sorcery_generic_alloc(sizeof(*endpoint), endpoint_destructor); @@ -809,11 +834,23 @@ void *ast_sip_endpoint_alloc(const char *name) ao2_cleanup(endpoint); return NULL; } - if (!(endpoint->codecs = ast_format_cap_alloc_nolock())) { + if (!(endpoint->media.codecs = ast_format_cap_alloc_nolock())) { ao2_cleanup(endpoint); return NULL; } - ast_party_id_init(&endpoint->id); + if (init_subscription_configuration(&endpoint->subscription)) { + ao2_cleanup(endpoint); + return NULL; + } + if (init_info_configuration(&endpoint->info)) { + ao2_cleanup(endpoint); + return NULL; + } + if (init_media_configuration(&endpoint->media)) { + ao2_cleanup(endpoint); + return NULL; + } + ast_party_id_init(&endpoint->id.self); return endpoint; } @@ -826,14 +863,14 @@ struct ao2_container *ast_sip_get_endpoints(void) return endpoints; } -int ast_sip_retrieve_auths(const char *auth_names[], size_t num_auths, struct ast_sip_auth **out) +int ast_sip_retrieve_auths(const struct ast_sip_auth_array *auths, struct ast_sip_auth **out) { int i; - for (i = 0; i < num_auths; ++i) { - out[i] = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), SIP_SORCERY_AUTH_TYPE, auth_names[i]); + for (i = 0; i < auths->num; ++i) { + out[i] = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), SIP_SORCERY_AUTH_TYPE, auths->names[i]); if (!out[i]) { - ast_log(LOG_NOTICE, "Couldn't find auth '%s'. Cannot authenticate\n", auth_names[i]); + ast_log(LOG_NOTICE, "Couldn't find auth '%s'. Cannot authenticate\n", auths->names[i]); return -1; } } diff --git a/res/res_sip/sip_distributor.c b/res/res_sip/sip_distributor.c index 95b28c0e7..d3615478f 100644 --- a/res/res_sip/sip_distributor.c +++ b/res/res_sip/sip_distributor.c @@ -170,7 +170,7 @@ static int create_artificial_endpoint(void) return -1; } - artificial_endpoint->num_inbound_auths = 1; + artificial_endpoint->inbound_auths.num = 1; return 0; } diff --git a/res/res_sip/sip_options.c b/res/res_sip/sip_options.c index 786711a37..a580684af 100644 --- a/res/res_sip/sip_options.c +++ b/res/res_sip/sip_options.c @@ -234,8 +234,7 @@ static void qualify_contact_cb(void *token, pjsip_event *e) endpoint should do that matched on the contact */ endpoint = ao2_callback(endpoints, 0, NULL, NULL); - if (!ast_sip_create_request_with_auth(endpoint->sip_outbound_auths, - endpoint->num_outbound_auths, + if (!ast_sip_create_request_with_auth(&endpoint->outbound_auths, challenge, tsx, &tdata)) { pjsip_endpt_send_request(ast_sip_get_pjsip_endpoint(), tdata, -1, NULL, NULL); diff --git a/res/res_sip/sip_outbound_auth.c b/res/res_sip/sip_outbound_auth.c index 94352a521..d31a52628 100644 --- a/res/res_sip/sip_outbound_auth.c +++ b/res/res_sip/sip_outbound_auth.c @@ -61,7 +61,7 @@ static pj_bool_t outbound_auth(pjsip_rx_data *rdata) return PJ_FALSE; } - if (ast_sip_create_request_with_auth(endpoint->sip_outbound_auths, endpoint->num_outbound_auths, rdata, tsx, &tdata)) { + if (ast_sip_create_request_with_auth(&endpoint->outbound_auths, rdata, tsx, &tdata)) { return PJ_FALSE; } diff --git a/res/res_sip_authenticator_digest.c b/res/res_sip_authenticator_digest.c index 8e3ff6de7..8b6399b58 100644 --- a/res/res_sip_authenticator_digest.c +++ b/res/res_sip_authenticator_digest.c @@ -41,7 +41,7 @@ AO2_GLOBAL_OBJ_STATIC(entity_id); */ static int digest_requires_authentication(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata) { - return endpoint->num_inbound_auths > 0; + return endpoint->inbound_auths.num > 0; } static void auth_store_cleanup(void *data) @@ -380,8 +380,8 @@ static enum ast_sip_check_auth_result digest_check_auth(struct ast_sip_endpoint RAII_VAR(struct ast_sip_endpoint *, artificial_endpoint, ast_sip_get_artificial_endpoint(), ao2_cleanup); - auths = ast_alloca(endpoint->num_inbound_auths * sizeof(*auths)); - verify_res = ast_alloca(endpoint->num_inbound_auths * sizeof(*verify_res)); + auths = ast_alloca(endpoint->inbound_auths.num * sizeof(*auths)); + verify_res = ast_alloca(endpoint->inbound_auths.num * sizeof(*verify_res)); if (!auths) { return AST_SIP_AUTHENTICATION_ERROR; @@ -389,12 +389,12 @@ static enum ast_sip_check_auth_result digest_check_auth(struct ast_sip_endpoint if (endpoint == artificial_endpoint) { auths[0] = ast_sip_get_artificial_auth(); - } else if (ast_sip_retrieve_auths(endpoint->sip_inbound_auths, endpoint->num_inbound_auths, auths)) { + } else if (ast_sip_retrieve_auths(&endpoint->inbound_auths, auths)) { res = AST_SIP_AUTHENTICATION_ERROR; goto cleanup; } - for (i = 0; i < endpoint->num_inbound_auths; ++i) { + for (i = 0; i < endpoint->inbound_auths.num; ++i) { verify_res[i] = verify(auths[i], rdata, tdata->pool); if (verify_res[i] == AUTH_SUCCESS) { res = AST_SIP_AUTHENTICATION_SUCCESS; @@ -402,14 +402,14 @@ static enum ast_sip_check_auth_result digest_check_auth(struct ast_sip_endpoint } } - for (i = 0; i < endpoint->num_inbound_auths; ++i) { + for (i = 0; i < endpoint->inbound_auths.num; ++i) { challenge(auths[i]->realm, tdata, rdata, verify_res[i] == AUTH_STALE); } res = AST_SIP_AUTHENTICATION_CHALLENGE; cleanup: - ast_sip_cleanup_auths(auths, endpoint->num_inbound_auths); + ast_sip_cleanup_auths(auths, endpoint->inbound_auths.num); return res; } diff --git a/res/res_sip_caller_id.c b/res/res_sip_caller_id.c index be88606f5..3ccf84057 100644 --- a/res/res_sip_caller_id.c +++ b/res/res_sip_caller_id.c @@ -313,7 +313,7 @@ static void update_incoming_connected_line(struct ast_sip_session *session, pjsi { struct ast_party_id id; - if (!session->endpoint->trust_id_inbound) { + if (!session->endpoint->id.trust_inbound) { return; } @@ -344,12 +344,12 @@ static int caller_id_incoming_request(struct ast_sip_session *session, pjsip_rx_ { if (session->inv_session->state < PJSIP_INV_STATE_CONFIRMED) { /* Initial inbound INVITE. Set the session ID directly */ - if (session->endpoint->trust_id_inbound && + if (session->endpoint->id.trust_inbound && (!set_id_from_pai(rdata, &session->id) || !set_id_from_rpid(rdata, &session->id))) { return 0; } - ast_party_id_copy(&session->id, &session->endpoint->id); - if (!session->endpoint->id.number.valid) { + ast_party_id_copy(&session->id, &session->endpoint->id.self); + if (!session->endpoint->id.self.number.valid) { set_id_from_from(rdata, &session->id); } } else { @@ -615,13 +615,13 @@ static void add_id_headers(const struct ast_sip_session *session, pjsip_tx_data { if (((id->name.presentation & AST_PRES_RESTRICTION) == AST_PRES_RESTRICTED || (id->number.presentation & AST_PRES_RESTRICTION) == AST_PRES_RESTRICTED) && - !session->endpoint->trust_id_outbound) { + !session->endpoint->id.trust_outbound) { return; } - if (session->endpoint->send_pai) { + if (session->endpoint->id.send_pai) { add_pai_header(tdata, id); } - if (session->endpoint->send_rpid) { + if (session->endpoint->id.send_rpid) { add_rpid_header(tdata, id); } } @@ -648,7 +648,7 @@ static void caller_id_outgoing_request(struct ast_sip_session *session, pjsip_tx connected_id = ast_channel_connected_effective_id(session->channel); if (session->inv_session->state < PJSIP_INV_STATE_CONFIRMED && - (session->endpoint->trust_id_outbound || + (session->endpoint->id.trust_outbound || ((connected_id.name.presentation & AST_PRES_RESTRICTION) == AST_PRES_ALLOWED && (connected_id.number.presentation & AST_PRES_RESTRICTION) == AST_PRES_ALLOWED))) { /* Only change the From header on the initial outbound INVITE. Switching it @@ -662,8 +662,8 @@ static void caller_id_outgoing_request(struct ast_sip_session *session, pjsip_tx modify_id_header(tdata->pool, from, &connected_id); modify_id_header(dlg->pool, dlg->local.info, &connected_id); - if (should_queue_connected_line_update(session, &session->endpoint->id)) { - queue_connected_line_update(session, &session->endpoint->id); + if (should_queue_connected_line_update(session, &session->endpoint->id.self)) { + queue_connected_line_update(session, &session->endpoint->id.self); } } add_id_headers(session, tdata, &connected_id); diff --git a/res/res_sip_diversion.c b/res/res_sip_diversion.c index 70b1fc508..7936ed55c 100644 --- a/res/res_sip_diversion.c +++ b/res/res_sip_diversion.c @@ -280,7 +280,7 @@ static void get_redirecting_add_diversion(struct ast_sip_session *session, pjsip { struct ast_party_redirecting *data; - if (session->channel && session->endpoint->send_diversion && + if (session->channel && session->endpoint->id.send_diversion && (data = ast_channel_redirecting(session->channel))->count) { add_diversion_header(tdata, data); } diff --git a/res/res_sip_messaging.c b/res/res_sip_messaging.c index 10d47047f..da5bf0eca 100644 --- a/res/res_sip_messaging.c +++ b/res/res_sip_messaging.c @@ -402,8 +402,8 @@ static enum pjsip_status_code rx_data_to_ast_msg(pjsip_rx_data *rdata, struct as } /* endpoint name */ - if (endpt->id.name.valid) { - CHECK_RES(ast_msg_set_var(msg, "SIP_PEERNAME", endpt->id.name.str)); + if (endpt->id.self.name.valid) { + CHECK_RES(ast_msg_set_var(msg, "SIP_PEERNAME", endpt->id.self.name.str)); } CHECK_RES(headers_to_vars(rdata, msg)); diff --git a/res/res_sip_mwi.c b/res/res_sip_mwi.c index cb636dbbb..6b44d52d0 100644 --- a/res/res_sip_mwi.c +++ b/res/res_sip_mwi.c @@ -281,12 +281,12 @@ static int send_unsolicited_mwi_notify_to_contact(void *obj, void *arg, int flag return 0; } - if (!ast_strlen_zero(endpoint->mwi_from)) { + if (!ast_strlen_zero(endpoint->subscription.mwi.fromuser)) { pjsip_fromto_hdr *from = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_FROM, NULL); pjsip_name_addr *from_name_addr = (pjsip_name_addr *) from->uri; pjsip_sip_uri *from_uri = pjsip_uri_get_uri(from_name_addr->uri); - pj_strdup2(tdata->pool, &from_uri->user, endpoint->mwi_from); + pj_strdup2(tdata->pool, &from_uri->user, endpoint->subscription.mwi.fromuser); } switch (state) { @@ -627,18 +627,18 @@ static int create_mwi_subscriptions_for_endpoint(void *obj, void *arg, int flags char *mailboxes; char *mailbox; - if (ast_strlen_zero(endpoint->mailboxes)) { + if (ast_strlen_zero(endpoint->subscription.mwi.mailboxes)) { return 0; } - if (endpoint->aggregate_mwi) { + if (endpoint->subscription.mwi.aggregate) { aggregate_sub = mwi_subscription_alloc(endpoint, AST_SIP_NOTIFIER, 0, NULL); if (!aggregate_sub) { return 0; } } - mailboxes = ast_strdupa(endpoint->mailboxes); + mailboxes = ast_strdupa(endpoint->subscription.mwi.mailboxes); while ((mailbox = strsep(&mailboxes, ","))) { struct mwi_subscription *sub = aggregate_sub ?: mwi_subscription_alloc(endpoint, AST_SIP_SUBSCRIBER, 0, NULL); diff --git a/res/res_sip_nat.c b/res/res_sip_nat.c index c18cac36a..2776cfeb6 100644 --- a/res/res_sip_nat.c +++ b/res/res_sip_nat.c @@ -40,7 +40,7 @@ static pj_bool_t nat_on_rx_request(pjsip_rx_data *rdata) return PJ_FALSE; } - if (endpoint->rewrite_contact && (contact = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, NULL)) && + if (endpoint->nat.rewrite_contact && (contact = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, NULL)) && (PJSIP_URI_SCHEME_IS_SIP(contact->uri) || PJSIP_URI_SCHEME_IS_SIPS(contact->uri))) { pjsip_sip_uri *uri = pjsip_uri_get_uri(contact->uri); @@ -48,7 +48,7 @@ static pj_bool_t nat_on_rx_request(pjsip_rx_data *rdata) uri->port = rdata->pkt_info.src_port; } - if (endpoint->force_rport) { + if (endpoint->nat.force_rport) { rdata->msg_info.via->rport_param = 0; } diff --git a/res/res_sip_one_touch_record_info.c b/res/res_sip_one_touch_record_info.c index 4e4b97355..d001dd828 100644 --- a/res/res_sip_one_touch_record_info.c +++ b/res/res_sip_one_touch_record_info.c @@ -62,9 +62,9 @@ static int handle_incoming_request(struct ast_sip_session *session, struct pjsip } if (!pj_stricmp2(&record->hvalue, "on")) { - feature = session->endpoint->recordonfeature; + feature = session->endpoint->info.recording.onfeature; } else if (!pj_stricmp2(&record->hvalue, "off")) { - feature = session->endpoint->recordofffeature; + feature = session->endpoint->info.recording.offfeature; } else { /* Don't send response because another module may handle this */ return 0; @@ -76,7 +76,7 @@ static int handle_incoming_request(struct ast_sip_session *session, struct pjsip } /* Is this endpoint configured with One Touch Recording? */ - if (!session->endpoint->one_touch_recording || ast_strlen_zero(feature)) { + if (!session->endpoint->info.recording.enabled || ast_strlen_zero(feature)) { send_response(session, 403, rdata); return 0; } diff --git a/res/res_sip_outbound_authenticator_digest.c b/res/res_sip_outbound_authenticator_digest.c index 13dc1f21b..d89bf7d4c 100644 --- a/res/res_sip_outbound_authenticator_digest.c +++ b/res/res_sip_outbound_authenticator_digest.c @@ -31,19 +31,19 @@ #include "asterisk/module.h" #include "asterisk/strings.h" -static int set_outbound_authentication_credentials(pjsip_auth_clt_sess *auth_sess, const char **auth_strs, size_t num_auths) +static int set_outbound_authentication_credentials(pjsip_auth_clt_sess *auth_sess, const struct ast_sip_auth_array *array) { - struct ast_sip_auth **auths = ast_alloca(num_auths * sizeof(*auths)); - pjsip_cred_info *auth_creds = ast_alloca(num_auths * sizeof(*auth_creds)); + struct ast_sip_auth **auths = ast_alloca(array->num * sizeof(*auths)); + pjsip_cred_info *auth_creds = ast_alloca(array->num * sizeof(*auth_creds)); int res = 0; int i; - if (ast_sip_retrieve_auths(auth_strs, num_auths, auths)) { + if (ast_sip_retrieve_auths(array, auths)) { res = -1; goto cleanup; } - for (i = 0; i < num_auths; ++i) { + for (i = 0; i < array->num; ++i) { pj_cstr(&auth_creds[i].realm, auths[i]->realm); pj_cstr(&auth_creds[i].username, auths[i]->auth_user); pj_cstr(&auth_creds[i].scheme, "digest"); @@ -62,14 +62,14 @@ static int set_outbound_authentication_credentials(pjsip_auth_clt_sess *auth_ses } } - pjsip_auth_clt_set_credentials(auth_sess, num_auths, auth_creds); + pjsip_auth_clt_set_credentials(auth_sess, array->num, auth_creds); cleanup: - ast_sip_cleanup_auths(auths, num_auths); + ast_sip_cleanup_auths(auths, array->num); return res; } -static int digest_create_request_with_auth(const char **auths, size_t num_auths, pjsip_rx_data *challenge, +static int digest_create_request_with_auth(const struct ast_sip_auth_array *auths, pjsip_rx_data *challenge, pjsip_transaction *tsx, pjsip_tx_data **new_request) { pjsip_auth_clt_sess auth_sess; @@ -80,7 +80,7 @@ static int digest_create_request_with_auth(const char **auths, size_t num_auths, return -1; } - if (set_outbound_authentication_credentials(&auth_sess, auths, num_auths)) { + if (set_outbound_authentication_credentials(&auth_sess, auths)) { ast_log(LOG_WARNING, "Failed to set authentication credentials\n"); return -1; } diff --git a/res/res_sip_outbound_registration.c b/res/res_sip_outbound_registration.c index 8ce16df69..a9351d95f 100644 --- a/res/res_sip_outbound_registration.c +++ b/res/res_sip_outbound_registration.c @@ -128,7 +128,7 @@ struct sip_outbound_registration_client_state { /*! \brief Serializer for stuff and things */ struct ast_taskprocessor *serializer; /*! \brief Configured authentication credentials */ - const char **sip_outbound_auths; + struct ast_sip_auth_array outbound_auths; /*! \brief Number of configured auths */ size_t num_outbound_auths; /*! \brief Registration should be destroyed after completion of transaction */ @@ -169,20 +169,11 @@ struct sip_outbound_registration { /*! \brief Outbound registration state */ struct sip_outbound_registration_state *state; /*! \brief Configured authentication credentials */ - const char **sip_outbound_auths; + struct ast_sip_auth_array outbound_auths; /*! \brief Number of configured auths */ size_t num_outbound_auths; }; -static void destroy_auths(const char **auths, size_t num_auths) -{ - int i; - for (i = 0; i < num_auths; ++i) { - ast_free((char *) auths[i]); - } - ast_free(auths); -} - /*! \brief Helper function which cancels the timer on a client */ static void cancel_registration(struct sip_outbound_registration_client_state *client_state) { @@ -270,7 +261,7 @@ static int handle_client_state_destruction(void *data) pjsip_regc_destroy(client_state->client); client_state->status = SIP_REGISTRATION_STOPPED; - destroy_auths(client_state->sip_outbound_auths, client_state->num_outbound_auths); + ast_sip_auth_array_destroy(&client_state->outbound_auths); return 0; } @@ -340,7 +331,7 @@ static int handle_registration_response(void *data) if (response->code == 401 || response->code == 407) { pjsip_tx_data *tdata; - if (!ast_sip_create_request_with_auth(response->client_state->sip_outbound_auths, response->client_state->num_outbound_auths, + if (!ast_sip_create_request_with_auth(&response->client_state->outbound_auths, response->rdata, response->tsx, &tdata)) { pjsip_regc_send(response->client_state->client, tdata); return 0; @@ -469,7 +460,7 @@ static void sip_outbound_registration_destroy(void *obj) struct sip_outbound_registration *registration = obj; ao2_cleanup(registration->state); - destroy_auths(registration->sip_outbound_auths, registration->num_outbound_auths); + ast_sip_auth_array_destroy(®istration->outbound_auths); ast_string_field_free_memory(registration); } @@ -568,7 +559,7 @@ static int can_reuse_registration(struct sip_outbound_registration *existing, st } for (i = 0; i < existing->num_outbound_auths; ++i) { - if (strcmp(existing->sip_outbound_auths[i], applied->sip_outbound_auths[i])) { + if (strcmp(existing->outbound_auths.names[i], applied->outbound_auths.names[i])) { return 0; } } @@ -667,15 +658,13 @@ static int sip_outbound_registration_perform(void *data) size_t i; /* Just in case the client state is being reused for this registration, free the auth information */ - destroy_auths(registration->state->client_state->sip_outbound_auths, - registration->state->client_state->num_outbound_auths); - registration->state->client_state->num_outbound_auths = 0; + ast_sip_auth_array_destroy(®istration->state->client_state->outbound_auths); - registration->state->client_state->sip_outbound_auths = ast_calloc(registration->num_outbound_auths, sizeof(char *)); - for (i = 0; i < registration->num_outbound_auths; ++i) { - registration->state->client_state->sip_outbound_auths[i] = ast_strdup(registration->sip_outbound_auths[i]); + registration->state->client_state->outbound_auths.names = ast_calloc(registration->outbound_auths.num, sizeof(char *)); + for (i = 0; i < registration->outbound_auths.num; ++i) { + registration->state->client_state->outbound_auths.names[i] = ast_strdup(registration->outbound_auths.names[i]); } - registration->state->client_state->num_outbound_auths = registration->num_outbound_auths; + registration->state->client_state->outbound_auths.num = registration->outbound_auths.num; registration->state->client_state->retry_interval = registration->retry_interval; registration->state->client_state->max_retries = registration->max_retries; registration->state->client_state->retries = 0; @@ -708,47 +697,11 @@ static void sip_outbound_registration_perform_all(void) ao2_iterator_destroy(&i); } -#define AUTH_INCREMENT 4 - -static const char **auth_alloc(const char *value, size_t *num_auths) -{ - char *auths = ast_strdupa(value); - char *val; - int num_alloced = 0; - const char **alloced_auths = NULL; - - while ((val = strsep(&auths, ","))) { - if (*num_auths >= num_alloced) { - size_t size; - num_alloced += AUTH_INCREMENT; - size = num_alloced * sizeof(char *); - alloced_auths = ast_realloc(alloced_auths, size); - if (!alloced_auths) { - goto failure; - } - } - alloced_auths[*num_auths] = ast_strdup(val); - if (!alloced_auths[*num_auths]) { - goto failure; - } - ++(*num_auths); - } - return alloced_auths; - -failure: - destroy_auths(alloced_auths, *num_auths); - return NULL; -} - static int outbound_auth_handler(const struct aco_option *opt, struct ast_variable *var, void *obj) { struct sip_outbound_registration *registration = obj; - registration->sip_outbound_auths = auth_alloc(var->value, ®istration->num_outbound_auths); - if (!registration->sip_outbound_auths) { - return -1; - } - return 0; + return ast_sip_auth_array_init(®istration->outbound_auths, var->value); } static int load_module(void) diff --git a/res/res_sip_pubsub.c b/res/res_sip_pubsub.c index 2f2b52463..ad20947a5 100644 --- a/res/res_sip_pubsub.c +++ b/res/res_sip_pubsub.c @@ -625,7 +625,7 @@ static pj_bool_t pubsub_on_rx_subscribe_request(pjsip_rx_data *rdata) endpoint = ast_pjsip_rdata_get_endpoint(rdata); ast_assert(endpoint != NULL); - if (!endpoint->allowsubscribe) { + if (!endpoint->subscription.allow) { ast_log(LOG_WARNING, "Subscriptions not permitted for endpoint %s.\n", ast_sorcery_object_get_id(endpoint)); pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 603, NULL, NULL, NULL); return PJ_TRUE; @@ -633,9 +633,9 @@ static pj_bool_t pubsub_on_rx_subscribe_request(pjsip_rx_data *rdata) expires_header = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES, rdata->msg_info.msg->hdr.next); - if (expires_header && expires_header->ivalue < endpoint->subminexpiry) { + if (expires_header && expires_header->ivalue < endpoint->subscription.minexpiry) { ast_log(LOG_WARNING, "Subscription expiration %d is too brief for endpoint %s. Minimum is %d\n", - expires_header->ivalue, ast_sorcery_object_get_id(endpoint), endpoint->subminexpiry); + expires_header->ivalue, ast_sorcery_object_get_id(endpoint), endpoint->subscription.minexpiry); pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 423, NULL, NULL, NULL); return PJ_TRUE; } diff --git a/res/res_sip_sdp_rtp.c b/res/res_sip_sdp_rtp.c index 6e994116d..4670fe2be 100644 --- a/res/res_sip_sdp_rtp.c +++ b/res/res_sip_sdp_rtp.c @@ -108,22 +108,22 @@ static int create_rtp(struct ast_sip_session *session, struct ast_sip_session_me { struct ast_rtp_engine_ice *ice; - if (!(session_media->rtp = ast_rtp_instance_new(session->endpoint->rtp_engine, sched, ipv6 ? &address_ipv6 : &address_ipv4, NULL))) { - ast_log(LOG_ERROR, "Unable to create RTP instance using RTP engine '%s'\n", session->endpoint->rtp_engine); + if (!(session_media->rtp = ast_rtp_instance_new(session->endpoint->media.rtp.engine, sched, ipv6 ? &address_ipv6 : &address_ipv4, NULL))) { + ast_log(LOG_ERROR, "Unable to create RTP instance using RTP engine '%s'\n", session->endpoint->media.rtp.engine); return -1; } ast_rtp_instance_set_prop(session_media->rtp, AST_RTP_PROPERTY_RTCP, 1); - ast_rtp_instance_set_prop(session_media->rtp, AST_RTP_PROPERTY_NAT, session->endpoint->rtp_symmetric); + ast_rtp_instance_set_prop(session_media->rtp, AST_RTP_PROPERTY_NAT, session->endpoint->media.rtp.symmetric); ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(session_media->rtp), - session_media->rtp, &session->endpoint->prefs); + session_media->rtp, &session->endpoint->media.prefs); if (session->endpoint->dtmf == AST_SIP_DTMF_INBAND) { ast_rtp_instance_dtmf_mode_set(session_media->rtp, AST_RTP_DTMF_MODE_INBAND); } - if (!session->endpoint->ice_support && (ice = ast_rtp_instance_get_ice(session_media->rtp))) { + if (!session->endpoint->media.rtp.ice_support && (ice = ast_rtp_instance_get_ice(session_media->rtp))) { ice->stop(session_media->rtp); } @@ -134,13 +134,13 @@ static int create_rtp(struct ast_sip_session *session, struct ast_sip_session_me } if (!strcmp(session_media->stream_type, STR_AUDIO) && - (session->endpoint->tos_audio || session->endpoint->cos_video)) { - ast_rtp_instance_set_qos(session_media->rtp, session->endpoint->tos_audio, - session->endpoint->cos_audio, "SIP RTP Audio"); + (session->endpoint->media.tos_audio || session->endpoint->media.cos_video)) { + ast_rtp_instance_set_qos(session_media->rtp, session->endpoint->media.tos_audio, + session->endpoint->media.cos_audio, "SIP RTP Audio"); } else if (!strcmp(session_media->stream_type, STR_VIDEO) && - (session->endpoint->tos_video || session->endpoint->cos_video)) { - ast_rtp_instance_set_qos(session_media->rtp, session->endpoint->tos_video, - session->endpoint->cos_video, "SIP RTP Video"); + (session->endpoint->media.tos_video || session->endpoint->media.cos_video)) { + ast_rtp_instance_set_qos(session_media->rtp, session->endpoint->media.tos_video, + session->endpoint->media.cos_video, "SIP RTP Video"); } return 0; @@ -213,9 +213,9 @@ static int set_caps(struct ast_sip_session *session, struct ast_sip_session_medi /* get the endpoint capabilities */ if (direct_media_enabled) { - ast_format_cap_joint_copy(session->endpoint->codecs, session->direct_media_cap, caps); + ast_format_cap_joint_copy(session->endpoint->media.codecs, session->direct_media_cap, caps); } else { - ast_format_cap_copy(caps, session->endpoint->codecs); + ast_format_cap_copy(caps, session->endpoint->media.codecs); } format_cap_only_type(caps, media_type); @@ -246,7 +246,7 @@ static int set_caps(struct ast_sip_session *session, struct ast_sip_session_medi if (session->channel) { ast_format_cap_copy(caps, ast_channel_nativeformats(session->channel)); ast_format_cap_remove_bytype(caps, media_type); - ast_codec_choose(&session->endpoint->prefs, joint, 1, &fmt); + ast_codec_choose(&session->endpoint->media.prefs, joint, 1, &fmt); ast_format_cap_add(caps, &fmt); /* Apply the new formats to the channel, potentially changing read/write formats while doing so */ @@ -328,7 +328,7 @@ static void add_ice_to_stream(struct ast_sip_session *session, struct ast_sip_se struct ao2_iterator it_candidates; struct ast_rtp_engine_ice_candidate *candidate; - if (!session->endpoint->ice_support || !(ice = ast_rtp_instance_get_ice(session_media->rtp)) || + if (!session->endpoint->media.rtp.ice_support || !(ice = ast_rtp_instance_get_ice(session_media->rtp)) || !(candidates = ice->get_local_candidates(session_media->rtp))) { return; } @@ -387,7 +387,7 @@ static void process_ice_attributes(struct ast_sip_session *session, struct ast_s unsigned int attr_i; /* If ICE support is not enabled or available exit early */ - if (!session->endpoint->ice_support || !(ice = ast_rtp_instance_get_ice(session_media->rtp))) { + if (!session->endpoint->media.rtp.ice_support || !(ice = ast_rtp_instance_get_ice(session_media->rtp))) { return; } @@ -466,7 +466,7 @@ static void apply_packetization(struct ast_sip_session *session, struct ast_sip_ struct ast_codec_pref *pref = &ast_rtp_instance_get_codecs(session_media->rtp)->pref; /* Apply packetization if available and configured to do so */ - if (!session->endpoint->use_ptime || !(attr = pjmedia_sdp_media_find_attr2(remote_stream, "ptime", NULL))) { + if (!session->endpoint->media.rtp.use_ptime || !(attr = pjmedia_sdp_media_find_attr2(remote_stream, "ptime", NULL))) { return; } @@ -517,7 +517,7 @@ static enum ast_sip_session_media_encryption check_endpoint_media_transport( { enum ast_sip_session_media_encryption incoming_encryption; - if (endpoint->use_avpf) { + if (endpoint->media.rtp.use_avpf) { char transport_end = stream->desc.transport.ptr[stream->desc.transport.slen - 1]; if (transport_end != 'F') { return AST_SIP_MEDIA_TRANSPORT_INVALID; @@ -526,7 +526,7 @@ static enum ast_sip_session_media_encryption check_endpoint_media_transport( incoming_encryption = get_media_encryption_type(stream->desc.transport); - if (incoming_encryption == endpoint->media_encryption) { + if (incoming_encryption == endpoint->media.rtp.encryption) { return incoming_encryption; } @@ -557,7 +557,7 @@ static int setup_dtls_srtp(struct ast_sip_session *session, { struct ast_rtp_engine_dtls *dtls; - if (!session->endpoint->dtls_cfg.enabled || !session_media->rtp) { + if (!session->endpoint->media.rtp.dtls_cfg.enabled || !session_media->rtp) { return -1; } @@ -566,8 +566,8 @@ static int setup_dtls_srtp(struct ast_sip_session *session, return -1; } - session->endpoint->dtls_cfg.suite = ((session->endpoint->srtp_tag_32) ? AST_AES_CM_128_HMAC_SHA1_32 : AST_AES_CM_128_HMAC_SHA1_80); - if (dtls->set_configuration(session_media->rtp, &session->endpoint->dtls_cfg)) { + session->endpoint->media.rtp.dtls_cfg.suite = ((session->endpoint->media.rtp.srtp_tag_32) ? AST_AES_CM_128_HMAC_SHA1_32 : AST_AES_CM_128_HMAC_SHA1_80); + if (dtls->set_configuration(session_media->rtp, &session->endpoint->media.rtp.dtls_cfg)) { ast_log(LOG_ERROR, "Attempted to set an invalid DTLS-SRTP configuration on RTP instance '%p'\n", session_media->rtp); return -1; @@ -675,7 +675,7 @@ static int setup_media_encryption(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_media *stream) { - switch (session->endpoint->media_encryption) { + switch (session->endpoint->media.rtp.encryption) { case AST_SIP_MEDIA_ENCRYPT_SDES: if (setup_sdes_srtp(session_media, stream)) { return -1; @@ -706,7 +706,7 @@ static int negotiate_incoming_sdp_stream(struct ast_sip_session *session, struct enum ast_format_type media_type = stream_to_media_type(session_media->stream_type); /* If no type formats have been configured reject this stream */ - if (!ast_format_cap_has_type(session->endpoint->codecs, media_type)) { + if (!ast_format_cap_has_type(session->endpoint->media.codecs, media_type)) { return 0; } @@ -750,7 +750,7 @@ static int add_crypto_to_stream(struct ast_sip_session *session, static const pj_str_t STR_ACTPASS = { "actpass", 7 }; static const pj_str_t STR_HOLDCONN = { "holdconn", 8 }; - switch (session->endpoint->media_encryption) { + switch (session->endpoint->media.rtp.encryption) { case AST_SIP_MEDIA_ENCRYPT_NONE: case AST_SIP_MEDIA_TRANSPORT_INVALID: break; @@ -764,7 +764,7 @@ static int add_crypto_to_stream(struct ast_sip_session *session, crypto_attribute = ast_sdp_srtp_get_attrib(session_media->srtp, 0 /* DTLS running? No */, - session->endpoint->srtp_tag_32 /* 32 byte tag length? */); + session->endpoint->media.rtp.srtp_tag_32 /* 32 byte tag length? */); if (!crypto_attribute) { /* No crypto attribute to add, bad news */ return -1; @@ -860,13 +860,13 @@ static int create_outgoing_sdp_stream(struct ast_sip_session *session, struct as int use_override_prefs = session->override_prefs.formats[0].id; struct ast_codec_pref *prefs = use_override_prefs ? - &session->override_prefs : &session->endpoint->prefs; + &session->override_prefs : &session->endpoint->media.prefs; if ((use_override_prefs && !codec_pref_has_type(&session->override_prefs, media_type)) || - (!use_override_prefs && !ast_format_cap_has_type(session->endpoint->codecs, media_type))) { + (!use_override_prefs && !ast_format_cap_has_type(session->endpoint->media.codecs, media_type))) { /* If no type formats are configured don't add a stream */ return 0; - } else if (!session_media->rtp && create_rtp(session, session_media, session->endpoint->rtp_ipv6)) { + } else if (!session_media->rtp && create_rtp(session, session_media, session->endpoint->media.rtp.ipv6)) { return -1; } @@ -881,25 +881,25 @@ static int create_outgoing_sdp_stream(struct ast_sip_session *session, struct as media->desc.media = pj_str(session_media->stream_type); media->desc.transport = pj_str(ast_sdp_get_rtp_profile( - session->endpoint->media_encryption == AST_SIP_MEDIA_ENCRYPT_SDES, - session_media->rtp, session->endpoint->use_avpf)); + session->endpoint->media.rtp.encryption == AST_SIP_MEDIA_ENCRYPT_SDES, + session_media->rtp, session->endpoint->media.rtp.use_avpf)); /* Add connection level details */ if (direct_media_enabled) { ast_copy_string(hostip, ast_sockaddr_stringify_fmt(&session_media->direct_media_addr, AST_SOCKADDR_STR_ADDR), sizeof(hostip)); - } else if (ast_strlen_zero(session->endpoint->external_media_address)) { + } else if (ast_strlen_zero(session->endpoint->media.external_address)) { pj_sockaddr localaddr; - if (pj_gethostip(session->endpoint->rtp_ipv6 ? pj_AF_INET6() : pj_AF_INET(), &localaddr)) { + if (pj_gethostip(session->endpoint->media.rtp.ipv6 ? pj_AF_INET6() : pj_AF_INET(), &localaddr)) { return -1; } pj_sockaddr_print(&localaddr, hostip, sizeof(hostip), 2); } else { - ast_copy_string(hostip, session->endpoint->external_media_address, sizeof(hostip)); + ast_copy_string(hostip, session->endpoint->media.external_address, sizeof(hostip)); } media->conn->net_type = STR_IN; - media->conn->addr_type = session->endpoint->rtp_ipv6 ? STR_IP6 : STR_IP4; + media->conn->addr_type = session->endpoint->media.rtp.ipv6 ? STR_IP6 : STR_IP4; pj_strdup2(pool, &media->conn->addr, hostip); ast_rtp_instance_get_local_address(session_media->rtp, &addr); media->desc.port = direct_media_enabled ? ast_sockaddr_port(&session_media->direct_media_addr) : (pj_uint16_t) ast_sockaddr_port(&addr); @@ -914,9 +914,9 @@ static int create_outgoing_sdp_stream(struct ast_sip_session *session, struct as } if (direct_media_enabled) { - ast_format_cap_joint_copy(session->endpoint->codecs, session->direct_media_cap, caps); - } else if (ast_format_cap_is_empty(session->req_caps) || !ast_format_cap_has_joint(session->req_caps, session->endpoint->codecs)) { - ast_format_cap_copy(caps, session->endpoint->codecs); + ast_format_cap_joint_copy(session->endpoint->media.codecs, session->direct_media_cap, caps); + } else if (ast_format_cap_is_empty(session->req_caps) || !ast_format_cap_has_joint(session->req_caps, session->endpoint->media.codecs)) { + ast_format_cap_copy(caps, session->endpoint->media.codecs); } else { ast_format_cap_copy(caps, session->req_caps); } @@ -1013,7 +1013,7 @@ static int apply_negotiated_sdp_stream(struct ast_sip_session *session, struct a } /* Create an RTP instance if need be */ - if (!session_media->rtp && create_rtp(session, session_media, session->endpoint->rtp_ipv6)) { + if (!session_media->rtp && create_rtp(session, session_media, session->endpoint->media.rtp.ipv6)) { return -1; } diff --git a/res/res_sip_session.c b/res/res_sip_session.c index 22967c6ff..7f24dcc1b 100644 --- a/res/res_sip_session.c +++ b/res/res_sip_session.c @@ -1191,7 +1191,7 @@ struct ast_sip_session *ast_sip_session_create_outgoing(struct ast_sip_endpoint return NULL; } - if (pjsip_inv_create_uac(dlg, NULL, endpoint->extensions, &inv_session) != PJ_SUCCESS) { + if (pjsip_inv_create_uac(dlg, NULL, endpoint->extensions.flags, &inv_session) != PJ_SUCCESS) { pjsip_dlg_terminate(dlg); return NULL; } @@ -1200,8 +1200,8 @@ struct ast_sip_session *ast_sip_session_create_outgoing(struct ast_sip_endpoint #endif pjsip_timer_setting_default(&timer); - timer.min_se = endpoint->min_se; - timer.sess_expires = endpoint->sess_expires; + timer.min_se = endpoint->extensions.timer.min_se; + timer.sess_expires = endpoint->extensions.timer.sess_expires; pjsip_timer_init_session(inv_session, &timer); if (!(session = ast_sip_session_alloc(endpoint, inv_session))) { @@ -1324,7 +1324,7 @@ static pjsip_inv_session *pre_session_setup(pjsip_rx_data *rdata, const struct a pjsip_tx_data *tdata; pjsip_dialog *dlg; pjsip_inv_session *inv_session; - unsigned int options = endpoint->extensions; + unsigned int options = endpoint->extensions.flags; if (pjsip_inv_verify_request(rdata, &options, NULL, NULL, ast_sip_get_pjsip_endpoint(), &tdata) != PJ_SUCCESS) { if (tdata) { @@ -1462,8 +1462,8 @@ static int new_invite(void *data) } pjsip_timer_setting_default(&timer); - timer.min_se = invite->session->endpoint->min_se; - timer.sess_expires = invite->session->endpoint->sess_expires; + timer.min_se = invite->session->endpoint->extensions.timer.min_se; + timer.sess_expires = invite->session->endpoint->extensions.timer.sess_expires; pjsip_timer_init_session(invite->session->inv_session, &timer); /* At this point, we've verified what we can, so let's go ahead and send a 100 Trying out */ @@ -1959,11 +1959,11 @@ static struct pjmedia_sdp_session *create_local_sdp(pjsip_inv_session *inv, stru local->origin.id = offer->origin.id; } - pj_strdup2(inv->pool, &local->origin.user, session->endpoint->sdpowner); + pj_strdup2(inv->pool, &local->origin.user, session->endpoint->media.sdpowner); local->origin.net_type = STR_IN; - local->origin.addr_type = session->endpoint->rtp_ipv6 ? STR_IP6 : STR_IP4; + local->origin.addr_type = session->endpoint->media.rtp.ipv6 ? STR_IP6 : STR_IP4; local->origin.addr = *pj_gethostname(); - pj_strdup2(inv->pool, &local->name, session->endpoint->sdpsession); + pj_strdup2(inv->pool, &local->name, session->endpoint->media.sdpsession); /* Now let the handlers add streams of various types, pjmedia will automatically reorder the media streams for us */ successful = ao2_callback_data(session->media, OBJ_MULTIPLE, add_sdp_streams, local, session); diff --git a/res/res_sip_t38.c b/res/res_sip_t38.c index d9c57dec1..a710546a4 100644 --- a/res/res_sip_t38.c +++ b/res/res_sip_t38.c @@ -248,13 +248,13 @@ static int t38_initialize_session(struct ast_sip_session *session, struct ast_si } if (!(session_media->udptl = ast_udptl_new_with_bindaddr(NULL, NULL, 0, - session->endpoint->t38udptl_ipv6 ? &address_ipv6 : &address_ipv4))) { + session->endpoint->media.t38.ipv6 ? &address_ipv6 : &address_ipv4))) { return -1; } ast_channel_set_fd(session->channel, 5, ast_udptl_fd(session_media->udptl)); - ast_udptl_set_error_correction_scheme(session_media->udptl, session->endpoint->t38udptl_ec); - ast_udptl_setnat(session_media->udptl, session->endpoint->t38udptl_nat); + ast_udptl_set_error_correction_scheme(session_media->udptl, session->endpoint->media.t38.error_correction); + ast_udptl_setnat(session_media->udptl, session->endpoint->media.t38.nat); return 0; } @@ -386,7 +386,7 @@ static int t38_interpret_parameters(void *obj) static struct ast_frame *t38_framehook_write(struct ast_sip_session *session, struct ast_frame *f) { if (f->frametype == AST_FRAME_CONTROL && f->subclass.integer == AST_CONTROL_T38_PARAMETERS && - session->endpoint->t38udptl) { + session->endpoint->media.t38.enabled) { struct t38_parameters_task_data *data = t38_parameters_task_data_alloc(session, f); if (!data) { @@ -446,7 +446,7 @@ static void t38_attach_framehook(struct ast_sip_session *session) .event_cb = t38_framehook, }; - if ((ast_channel_state(session->channel) == AST_STATE_UP) || !session->endpoint->t38udptl) { + if ((ast_channel_state(session->channel) == AST_STATE_UP) || !session->endpoint->media.t38.enabled) { return; } @@ -533,8 +533,8 @@ static void t38_interpret_sdp(struct t38_state *state, struct ast_sip_session *s } else if (!pj_stricmp2(&attr->name, "t38faxversion")) { state->their_parms.version = pj_strtoul(&attr->value); } else if (!pj_stricmp2(&attr->name, "t38faxmaxdatagram") || !pj_stricmp2(&attr->name, "t38maxdatagram")) { - if (session->endpoint->t38udptl_maxdatagram) { - ast_udptl_set_far_max_datagram(session_media->udptl, session->endpoint->t38udptl_maxdatagram); + if (session->endpoint->media.t38.maxdatagram) { + ast_udptl_set_far_max_datagram(session_media->udptl, session->endpoint->media.t38.maxdatagram); } else { ast_udptl_set_far_max_datagram(session_media->udptl, pj_strtoul(&attr->value)); } @@ -569,7 +569,7 @@ static int defer_incoming_sdp_stream(struct ast_sip_session *session, struct ast { struct t38_state *state; - if (!session->endpoint->t38udptl) { + if (!session->endpoint->media.t38.enabled) { return 0; } @@ -600,7 +600,7 @@ static int negotiate_incoming_sdp_stream(struct ast_sip_session *session, struct char host[NI_MAXHOST]; RAII_VAR(struct ast_sockaddr *, addrs, NULL, ast_free_ptr); - if (!session->endpoint->t38udptl) { + if (!session->endpoint->media.t38.enabled) { return -1; } @@ -622,8 +622,8 @@ static int negotiate_incoming_sdp_stream(struct ast_sip_session *session, struct } /* Check the address family to make sure it matches configured */ - if ((ast_sockaddr_is_ipv6(addrs) && !session->endpoint->t38udptl_ipv6) || - (ast_sockaddr_is_ipv4(addrs) && session->endpoint->t38udptl_ipv6)) { + if ((ast_sockaddr_is_ipv6(addrs) && !session->endpoint->media.t38.ipv6) || + (ast_sockaddr_is_ipv4(addrs) && session->endpoint->media.t38.ipv6)) { /* The address does not match configured */ return -1; } @@ -652,7 +652,7 @@ static int create_outgoing_sdp_stream(struct ast_sip_session *session, struct as char tmp[512]; pj_str_t stmp; - if (!session->endpoint->t38udptl) { + if (!session->endpoint->media.t38.enabled) { return 1; } else if ((session->t38state != T38_LOCAL_REINVITE) && (session->t38state != T38_PEER_REINVITE) && (session->t38state != T38_ENABLED)) { @@ -671,19 +671,19 @@ static int create_outgoing_sdp_stream(struct ast_sip_session *session, struct as media->desc.media = pj_str(session_media->stream_type); media->desc.transport = STR_UDPTL; - if (ast_strlen_zero(session->endpoint->external_media_address)) { + if (ast_strlen_zero(session->endpoint->media.external_address)) { pj_sockaddr localaddr; - if (pj_gethostip(session->endpoint->t38udptl_ipv6 ? pj_AF_INET6() : pj_AF_INET(), &localaddr)) { + if (pj_gethostip(session->endpoint->media.t38.ipv6 ? pj_AF_INET6() : pj_AF_INET(), &localaddr)) { return -1; } pj_sockaddr_print(&localaddr, hostip, sizeof(hostip), 2); } else { - ast_copy_string(hostip, session->endpoint->external_media_address, sizeof(hostip)); + ast_copy_string(hostip, session->endpoint->media.external_address, sizeof(hostip)); } media->conn->net_type = STR_IN; - media->conn->addr_type = session->endpoint->t38udptl_ipv6 ? STR_IP6 : STR_IP4; + media->conn->addr_type = session->endpoint->media.t38.ipv6 ? STR_IP6 : STR_IP4; pj_strdup2(pool, &media->conn->addr, hostip); ast_udptl_get_us(session_media->udptl, &addr); media->desc.port = (pj_uint16_t) ast_sockaddr_port(&addr); -- cgit v1.2.3