Search the Asterisk Blog

Identifying an endpoint in PJSIP

By Richard Mudgett

A basic concept with chan_pjsip/res_pjsip is the endpoint. When a new SIP request comes in, res_pjsip needs to identify which endpoint the request is for. New incoming SIP requests are identified by various endpoint identifiers registered with res_pjsip. The various endpoint identifiers look for different things in the received request to determine which endpoint is recognized. The most used endpoint identifier uses the “From” header’s username to find an endpoint of the same name.

Endpoint identification matching priority

With several endpoint identifiers available, res_pjsip asks each identifier in turn if can match an endpoint with the request. The first endpoint identified handles the request message. It is possible that more than one endpoint identifier could identify an endpoint for the request. To bring some predictability to which endpoint is recognized, you can specify the order endpoint identifiers check the request with the global endpoint_identifier_order option.

The endpoint_identifier_order option is a comma separated list of endpoint identifier names. The order of the list is the specified order the named identifiers check the request. Any named identifiers not listed are checked last in the order they are registered. Any identifiers that have no name are checked first in the order they are registered.

If you issue the CLI command “pjsip show identifiers” you get the list of endpoint identifiers available on your system in the order they are checked. You can list any of the named endpoint identifiers on the endpoint_identifier_order option.

Endpoint identifier: anonymous

The “anonymous” endpoint is the functional equivalent to chan_sip’s allowguest feature.  By default anonymous inbound calls via PJSIP are not allowed as these calls can be placed by any device that can reach your server. However, to allow anonymous calls you need to create an endpoint named “anonymous” (or any of the variants listed below if the disable_multi_domain option is ‘no’) and load res_pjsip_endpoint_identifier_anonymous.so.

The order endpoint names are searched:

  1. anonymous@<domain> – The domain in the “From” header URI.
  2. anonymous@<domain-alias> – An alias for the “From” header URI domain specified by a “domain-alias” section.
  3. anonymous@<transport-domain> – The domain specified by the “transport” section of the transport the request came in on.
  4. anonymous

The “anonymous” endpoint identifier needs to be last in the endpoint_identifier_order list as it will always match the “anonymous” endpoint if it exists.

Endpoint identifier: username

The “username” endpoint identifier:

  • is registered by the res_pjsip_endpoint_identifier_user.so module.
  • supports registration of the endpoint devices with the server.
  • recognizes endpoints by looking up the username in the “From” header’s URI. Other endpoint name variants with domain names are searched for if the disable_multi_domain option is ‘no’.

The order endpoint names are searched:

  1. <username>@<domain> – The domain in the “From” header URI.
  2. <username>@<domain-alias> – An alias for the “From” header URI domain specified by a “domain-alias” section.
  3. <username>@<transport-domain> – The domain specified by the “transport” section of the transport the request came in on.
  4. <username>

If an endpoint is found then the endpoint’s identify_by option also needs to list the username endpoint identifier to allow the identification.

Endpoint identifier: auth_username

The “auth_username” endpoint identifier:

  • is registered by the res_pjsip_endpoint_identifier_user.so module.
  • supports registration of the endpoint devices with the server.
  • recognizes endpoints by looking up the digest username in the authorization headers. Other endpoint name variants with the digest realm and transport domain are searched for if the disable_multi_domain option is ‘no’.

The order endpoint names are searched:

  1. <username@realm> – The digest realm in the authorization header.
  2. <username@realm-alias> – An alias for the authorization header digest realm specified by a “domain-alias” section.
  3. <username@transport-domain> – The domain specified by the “transport” section of the transport the request came in on.
  4. <username>

If an endpoint is found then the endpoint’s identify_by option also needs to list the “auth_username” endpoint identifier to allow the identification.

Using the “auth_username” endpoint identifier has some security considerations. The initial request usually does not have authentication headers with digest authentication because the server has not challenged the request. The sender cannot generate the authentication headers until it receives a challenge. Since Asterisk normally sends a security event on unrecognized requests, the security event needs to be deferred. Delaying the security events can result in a delay before an attack is recognized. The following global res_pjsip options control these false security events only if “auth_username” is listed in the endpoint_identifier_order option: unidentified_request_count, unidentified_request_period, and unidentified_request_prune_interval.

Endpoint identifier: ip

The “ip” endpoint identifier:

  • is registered by the res_pjsip_endpoint_identifier_ip.so module.
  • recognizes the endpoint from the request’s source IP address in a configured “identify” section.

With an “identify” section you specify the endpoint to recognize when a request comes in from the specified source IP addresses or networks.

Endpoint identifier: header

The “header” endpoint identifier was extracted from the ip endpoint identifier by ASTERISK-27491 and will first be available in Asterisk 13.20.0 and 15.3.0.

The “header” endpoint identifier:

  • is registered by the res_pjsip_endpoint_identifier_ip.so module.
  • recognizes the endpoint from the request’s header and content in a configured “identify” section.

With an “identify” section you specify the endpoint to recognize when a request comes in with the exact header and contents in match_header. If there are alternate headers and contents to recognize the same endpoint then you need to configure an “identify” section for each.

Unnamed endpoint identifier

Loading the res_pjsip_outbound_registration.so module registers an unnamed endpoint identifier and uses it to handle “line” processing.  If “line” is enabled on an outbound registration, a “line” parameter is added to the outgoing “Contact” header which should be returned by the registrar in the request URI or the “To” header URI of incoming requests.  This identifier identifies the endpoint by using the value of the “line” parameter (if present) to find the corresponding outbound registration, then assigns the request to the endpoint in that registration.  Because the identifier has no name it is not configurable with endpoint_identifier_order and is always checked first.

No Comments Yet

Get the conversation started!

Add to the Discussion

Your email address will not be published. Required fields are marked *

About the Author

Richard Mudgett

Richard Mudgett is a Senior Software Developer at Digium. While a prolific developer and contributor to Asterisk, he's elusive and can be difficult to spot outside of his native #asterisk-dev environs. We were impressed we got him to write a blog post.

See All of Richard's Articles

More From
The Digium Blog

  • No items