--- a/res/res_pjsip_outbound_registration.c +++ b/res/res_pjsip_outbound_registration.c @@ -209,6 +209,9 @@ Enables advertising SIP Outbound support (RFC5626) for outbound REGISTER requests. + + Overrides the User-Agent-Header that should be used for outbound REGISTER requests. + @@ -341,6 +344,8 @@ struct sip_outbound_registration { AST_STRING_FIELD(outbound_proxy); /*! \brief Endpoint to use for related incoming calls */ AST_STRING_FIELD(endpoint); + /*! \brief User-Agent to use when sending the REGISTER-request */ + AST_STRING_FIELD(user_agent); ); /*! \brief Requested expiration time */ unsigned int expiration; @@ -431,6 +436,8 @@ struct sip_outbound_registration_client_state { char *registration_name; /*! \brief Expected time of registration lapse/expiration */ unsigned int registration_expires; + /*! \brief The value for the User-Agent header sent in requests */ + char *user_agent; }; /*! \brief Outbound registration state information (persists for lifetime that registration should exist) */ @@ -726,6 +733,26 @@ static pj_status_t registration_client_send(struct sip_outbound_registration_cli add_security_headers(client_state, tdata); /* + * Replace the User-Agent-header if a different one should be used + */ + if(!ast_strlen_zero(client_state->user_agent)) { + static const pj_str_t user_agent_str = { "User-Agent", 10 }; + pjsip_generic_string_hdr *user_agent_hdr; + pj_str_t user_agent_val; + user_agent_hdr = pjsip_msg_find_hdr_by_name(tdata->msg, &user_agent_str, NULL); + if(user_agent_hdr) { + pj_list_erase(user_agent_hdr); + } + user_agent_val = pj_str(client_state->user_agent); + user_agent_hdr = pjsip_generic_string_hdr_create(tdata->pool, &user_agent_str, &user_agent_val); + if (!user_agent_hdr) { + ast_log(LOG_ERROR, "Failed to create User-Agent header\n"); + } else { + pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr *)user_agent_hdr); + } + } + + /* * Set the transport in case transports were reloaded. * When pjproject removes the extraneous error messages produced, * we can check status and only set the transport and resend if there was an error @@ -1523,6 +1550,7 @@ static struct sip_outbound_registration_state *sip_outbound_registration_state_a state->client_state->transport_name = ast_strdup(registration->transport); state->client_state->registration_name = ast_strdup(ast_sorcery_object_get_id(registration)); + state->client_state->user_agent = ast_strdup(registration->user_agent); ast_statsd_log_string("PJSIP.registrations.count", AST_STATSD_GAUGE, "+1", 1.0); ast_statsd_log_string_va("PJSIP.registrations.state.%s", AST_STATSD_GAUGE, "+1", 1.0, @@ -2759,6 +2787,7 @@ static int load_module(void) ast_sorcery_object_field_register_custom(ast_sip_get_sorcery(), "registration", "security_mechanisms", "", security_mechanisms_handler, NULL, NULL, 0, 0); ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "line", "no", OPT_BOOL_T, 1, FLDSET(struct sip_outbound_registration, line)); ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "endpoint", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct sip_outbound_registration, endpoint)); + ast_sorcery_object_field_register(ast_sip_get_sorcery(), "registration", "user_agent", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct sip_outbound_registration, user_agent)); /* * Register sorcery observers.