Skip to content

Conversation

@maximilianfridrich
Copy link
Contributor

@maximilianfridrich maximilianfridrich commented Nov 7, 2025

res_pjsip: Introduce redirect module for handling 3xx responses
This commit introduces a new redirect handling module that provides
infrastructure for following SIP 3xx redirect responses. The redirect
functionality respects the endpoint's redirect_method setting and only
follows redirects when set to 'uri_pjsip'. This infrastructure can be
used by any PJSIP module that needs to handle 3xx redirect responses.

res_pjsip_messaging: Add support for following 3xx redirects
This commit integrates the redirect module into res_pjsip_messaging
to enable following 3xx redirect responses for outgoing SIP MESSAGEs.

When follow_redirect_methods contains 'message' on an endpoint, Asterisk
will now follow 3xx redirect responses for MESSAGEs, similar to how
it behaves for INVITE responses.

Resolves: #1576

UserNote: A new pjsip endpoint option follow_redirect_methods was added.
This option is a comma-delimited, case-insensitive list of SIP methods
for which SIP 3XX redirect responses are followed. An alembic upgrade
script has been added for adding this new option to the Asterisk
database.

@maximilianfridrich
Copy link
Contributor Author

cherry-pick-to: 20
cherry-pick-to: 22
cherry-pick-to: 23
multiple-commits: standalone
testsuite-test-pr: 117

@github-actions
Copy link

github-actions bot commented Nov 7, 2025

Workflow PRCheck completed successfully

@github-actions
Copy link

github-actions bot commented Nov 9, 2025

Workflow PRCheck completed successfully

@github-actions
Copy link

Workflow PRCheck completed successfully

/*!
* \brief Maximum size for a URI string
*/
#define AST_SIP_MAX_URI_SIZE 512
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason not to use the PJSIP defined one?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought there was a PJSIP defined one but I couldn't find it. I found it now and will use it. Thanks.

* SIP 3xx redirects, including visited URIs for loop detection,
* pending contacts for retry logic, and hop counting.
*/
struct ast_sip_redirect_context;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Context has a rather specific meaning within Asterisk, and I must admit on reading this name I thought it meant dialplan context and was confused until the brief description sunk in. I think a different name would eliminate that confusion. "ast_sip_redirect_state"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, thanks and sorry about the confusion. I'll rename everything to state.

* \brief Check if redirect should be followed based on endpoint configuration
*
* \param endpoint The SIP endpoint
* \param status_code The response status code
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The response status code from what?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I clarified the doc comment: "The status code from a SIP response message (e.g. 305)"

* \param contacts List to populate with parsed contacts
* \return Number of valid contacts found
*/
static int parse_redirect_contacts(pjsip_rx_data *rdata, struct redirect_contact_list *contacts)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pass in the state/context pointer, and use the endpoint to add name to the logging

I'm kind of a broken record lately with logging, but giving information on which endpoint is involved can be very valuable if someone goes back to try to understand what happened on a well used system

The same applies for the code going forward after this comment, I'm not going to comment on each one but I urge you to go back to each and try to make them more specific/detailed including endpoint name

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood. I tried to add the endpoint ID to the logs (mostly within the prose). Let me know if this is okay or if you would like it differently (e.g. a consistent format).

return -1;
}

ast_log(LOG_NOTICE, "Redirect: found %d Contact header%s\n", contact_count, contact_count == 1 ? "" : "s");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be removed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. Done.

{
struct message_response_data *resp_data;

resp_data = ao2_alloc(sizeof(*resp_data), message_response_data_destroy);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be allocated without a lock using ao2_alloc_options

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Done.

struct msg_data *mdata = data; /* The caller holds a reference */
/* Callback data for redirect handling */
struct message_response_data *resp_data;
char content_type_buf[128];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where did 128 come from?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Arbitrary. I thought that should be enough for the Content-Type header which contains a MIME type (potentially with parameters). I changed it now to a malloced ast_str which can grow if needed.

@maximilianfridrich
Copy link
Contributor Author

Thanks for the review @jcolp! I've incorporated your feedback and responded to your comments. Let me know what you think.

@github-actions
Copy link

Workflow PRCheck completed successfully

and also supporting multiple potential redirect targets. The con is that since redirection occurs
within chan_pjsip redirecting information is not forwarded and redirection can not be
prevented.
prevented. Further, if <literal>uri_pjsip</literal> is configured, 3xx responses to SIP MESSAGEs
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the follow_redirect_methods is good.


/* Check event type */
if (e->body.tsx_state.type == PJSIP_EVENT_TIMER) {
ast_debug(1, "MESSAGE request timed out\n");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs to include endpoint if present and be more specific "MESSAGE request timed out on sending to endpoint %s\n"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

This commit introduces a new redirect handling module that provides
infrastructure for following SIP 3xx redirect responses. The redirect
functionality respects the endpoint's redirect_method setting and only
follows redirects when set to 'uri_pjsip'. This infrastructure can be
used by any PJSIP module that needs to handle 3xx redirect responses.
@maximilianfridrich
Copy link
Contributor Author

Thanks again for another review @jcolp! I've incorporated your feedback, created the new config option follow_redirect_methods with corresponding alembic migration and adapted the testsuite PR accordingly to use this new option.

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Attention! This pull request may contain issues that could prevent it from being accepted. Please review the checklist below and take the recommended action. If you believe any of these are not applicable, just add a comment and let us know.

  • An Alembic change was detected but a commit message UpgradeNote with at least one of the 'alembic', 'database' or 'schema' keywords wasn't found. Please add an UpgradeNote to the commit message that mentions one of those keywords notifying users that there's a database schema change.

Documentation:

@github-actions github-actions bot added the has-pr-checklist A PR Checklist is present on the PR label Dec 12, 2025
@github-actions
Copy link

Workflow PRCheck completed successfully

This commit integrates the redirect module into res_pjsip_messaging
to enable following 3xx redirect responses for outgoing SIP MESSAGEs.

When follow_redirect_methods contains 'message' on an endpoint, Asterisk
will now follow 3xx redirect responses for MESSAGEs, similar to how
it behaves for INVITE responses.

Resolves: asterisk#1576

UserNote: A new pjsip endpoint option follow_redirect_methods was added.
This option is a comma-delimited, case-insensitive list of SIP methods
for which SIP 3XX redirect responses are followed. An alembic upgrade
script has been added for adding this new option to the Asterisk
database.
@github-actions
Copy link

Workflow PRCheck failed
master-pjs5: FAILED TEST: channels/pjsip/subscriptions/rls/lists_of_lists/nominal/mwi/batched

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

has-pr-checklist A PR Checklist is present on the PR pr-submit-tests-failed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[improvement]: res_pjsip_messaging: Follow 3xx redirect messages if redirect_method=uri_pjsip

2 participants