# OpenSIPS

[OpenSIPS](https://ce.opensips.org/#about-us) is an open-source SIP signaling server
for routing calls between SIP devices, PBX systems, and service providers.

This guide explains how to connect **OpenSIPS 4.0** to **DIDWW SIP
Trunking** for inbound and outbound calling. It covers configuring DIDWW
inbound and outbound SIP trunks, assigning DID numbers, and routing calls
between DIDWW and a user agent behind OpenSIPS.

The inbound configuration supports Static Endpoint and Dynamic Registration
trunks. The outbound configuration uses SIP digest authentication. No
database is required.

Important

OpenSIPS handles SIP signaling only in this configuration. A user agent
is required to handle call media. Add the user agent's public RTP address
to the allowed RTP addresses of the DIDWW inbound and outbound trunks.

---

## 1. Configure inbound voice trunk

Configure an Inbound SIP Trunk in the DIDWW User Panel to send incoming calls
from your DIDWW numbers to OpenSIPS. Select the delivery method that matches
your OpenSIPS deployment.

### Before you begin

- An active DIDWW account is required. [Sign in to DIDWW](https://my.didww.com/users/sign_in) or [create a DIDWW account](https://my.didww.com/users/sign_up#/users/sign_up).
- At least one active **DID number** with capacity to receive incoming calls
  is required. If you do not have one, see
  [How to buy numbers](../../phone-numbers/buy-numbers/how-to-buy.html).

### Step 1: Create New Inbound SIP trunk

1. In the [DIDWW User Panel](https://my.didww.com/#/trunks), go to
   **Voice > Inbound Trunks**.
2. Click **Create New > SIP Trunk**.

[![Creating a new inbound SIP trunk](../../_images/create-inbound-sip-trunk2.png)](../../_images/create-inbound-sip-trunk2.png)


Creating a new inbound SIP trunk.

### Step 2: Configure general SIP trunk settings

In the Create Inbound SIP Trunk form, enter the settings for the selected
trunk type.

Static Endpoint

1. Enter a descriptive **Name** for the trunk (e.g., `OpenSIPS`).
2. Select **Static Endpoint** as the trunk **Type**.
3. In **Host**, enter the public IP address of the OpenSIPS server or a
   domain name that resolves to it.
4. Select **UDP** as the signaling **Transport** and enter `5060` as
   the **Port**. These values must match the [OpenSIPS listening
   socket](#opensips-configure-socket).
5. Set **User Part of R-URI** to `{DID}`. This placeholder inserts the
   called DID in E.164 format into the user part of the Request-URI.
6. Leave **Preferred Server** at **Auto** unless calls must originate
   from a specific Point of Presence.

[![Configuring a Static Endpoint inbound SIP trunk for OpenSIPS](../../_images/configure-static-endpoint2.webp)](../../_images/configure-static-endpoint2.webp)


Static Endpoint trunk settings.


Dynamic Registration

1. Enter a descriptive **Name** for the trunk (e.g., `OpenSIPS`).
2. Select **Dynamic Registration** as the trunk **Type**.
3. Configure the remaining media and signaling settings required by
   your deployment.

[![Configuring Dynamic Registration and Use DID in R-URI for OpenSIPS](../../_images/configure-dynamic-registration2.webp)](../../_images/configure-dynamic-registration2.webp)


Dynamic Registration trunk settings.

For either trunk type, open **Media & DTMF** and configure the following:

1. Enter the user agent's public RTP address in **Allowed RTP IP Addresses**.
   OpenSIPS does not relay RTP in this configuration.
2. Enable **Force Symmetric RTP** if the user agent is behind NAT.

Important

Keep **Allowed RTP IP Addresses** configured when using **Force Symmetric
RTP** to restrict accepted media sources. Leaving the address list empty
allows RTP from any source.

[![Configuring codecs and allowed RTP addresses for the user agent](../../_images/configure-inbound-media.webp)](../../_images/configure-inbound-media.webp)


Inbound trunk media settings.

### Step 3: Click Create and Save Inbound SIP Trunk Configuration

When all required fields in the Create Inbound SIP Trunk form are filled,
click **Create** to save the trunk.

Note

For advanced SIP trunk configuration, see
[Advanced Inbound SIP Trunk documentation](../../voice/inbound-trunks/creating-a-new-sip-trunk.html#user-panel-sipin-trunk-advanced-configuration).

Static Endpoint

[![Saving the OpenSIPS Static Endpoint inbound SIP trunk](../../_images/save-static-inbound-trunk2.webp)](../../_images/save-static-inbound-trunk2.webp)


Creating the Static Endpoint inbound SIP trunk.


Dynamic Registration

[![Saving the OpenSIPS Dynamic Registration inbound SIP trunk](../../_images/save-dynamic-inbound-trunk2.webp)](../../_images/save-dynamic-inbound-trunk2.webp)


Creating the Dynamic Registration inbound SIP trunk.

### Step 4: Copy Inbound Trunk Credentials (Dynamic Registration Only)

For a Dynamic Registration trunk, open the created trunk and copy its
generated username, password, and registration endpoint. You will use these
values when you [register the inbound trunk](#opensips-register-inbound).
Static Endpoint trunks do not use registration credentials.

Note

The example registers with `sip.didww.com`. A regional endpoint such as
`ams.sip.didww.com` registers the trunk with a specific location.
OpenSIPS takes the registration digest realm from the registrar's challenge.

[![Viewing generated Dynamic Registration credentials and endpoints](../../_images/inbound-registration-credentials2.webp)](../../_images/inbound-registration-credentials2.webp)


Dynamic Registration credentials and endpoints.

### Step 5: Assign inbound SIP trunk to your DID numbers

After creating the Inbound SIP Trunk for OpenSIPS, assign it to the DID
number(s) that will deliver incoming calls to OpenSIPS.

1. In the DIDWW User Panel, go to **Phone Numbers > My Numbers**.
2. Select the DID number(s) you want to assign to the inbound SIP trunk.
3. At the bottom of the page, click **Batch Actions > Update Trunks**.

[![Selecting DID numbers and Update Trunks from the Batch Actions menu](../../_images/select-dids-update-trunks2.webp)](../../_images/select-dids-update-trunks2.webp)


Selecting **Update Trunks** from the Batch Actions menu.

4. From the dropdown menu, choose the **OpenSIPS SIP trunk** created in
   [Step 3](#opensips-save-inbound-trunk).
5. Click **Confirm** to apply the changes.

[![Assigning the OpenSIPS inbound SIP trunk to DID numbers](../../_images/assign-inbound-trunk2.webp)](../../_images/assign-inbound-trunk2.webp)


Assigning the newly created SIP trunk to the selected DID(s).



---

## 2. Configure outbound voice trunk

Configure an Outbound SIP Trunk in the DIDWW User Panel to allow OpenSIPS to
place outbound calls through DIDWW. This trunk provides the SIP credentials
and routing settings required for outbound calls to external phone numbers.

### Before you begin

Access to **DIDWW Outbound Trunks** is required for making outbound calls.
See [Get access to outbound trunks](../../voice/outbound-trunks/get-access.html#user-panel-voice-out-get-access).

### Step 1: Create New Outbound SIP Trunk

1. In the [DIDWW User Panel](https://my.didww.com/#/trunks), go to
   **Voice > Outbound Trunks**.
2. Click **Create New**.

[![Creating a new outbound SIP trunk](../../_images/create-outbound-sip-trunk2.png)](../../_images/create-outbound-sip-trunk2.png)


Creating a new outbound SIP trunk.

### Step 2: Configure Authentication

1. Update the **Friendly Name** (e.g., `OpenSIPS`).
2. Keep the default **Credentials & IP-Based** authentication method selected.
   The SIP digest credentials will be provided after the trunk is created.
3. Leave **Tech Prefix** empty for this example.
4. In **Allowed SIP IP addresses**, enter the public IP address or subnet
   from which OpenSIPS will send outbound SIP traffic.
5. In **Allowed RTP IP addresses**, enter the public address from which the
   user agent will send RTP.
6. Configure **Allowed CLI(s)** and the other termination settings required
   by your deployment.

Note

At least one **Allowed SIP IP address** is required. The trunk accepts up
to 60 SIP addresses or subnets. If you configure a **Tech Prefix**, the
outgoing Request-URI must include it before the dialed number.

[![Configuring authentication and allowed SIP and RTP addresses for OpenSIPS](../../_images/configure-outbound-trunk2.webp)](../../_images/configure-outbound-trunk2.webp)


Outbound trunk authentication settings.

Important

The caller ID must match the value set by `uac_replace_from()` in the
[OpenSIPS outbound route](#opensips-configure-outbound-routing).
A call can pass digest authentication and still be rejected by the trunk's
CLI or destination settings.

### Step 3: Click Create and Save Outbound SIP Trunk Configuration

When all required fields in the Create Outbound SIP Trunk form are filled,
click **Create** to save the trunk.

Note

For advanced outbound SIP trunk configuration, see
[Outbound SIP Trunk Guide](../../voice/outbound-trunks/how-to-guides/index.html#outbound-trunk-create).

[![Saving the OpenSIPS outbound SIP trunk](../../_images/save-outbound-trunk2.webp)](../../_images/save-outbound-trunk2.webp)


Creating the outbound SIP trunk.

Note

Check that the trunk's **Status** is enabled before testing calls. Reaching
the rolling 24-hour limit disables the trunk, blocks new calls, and
disconnects active calls shortly afterward. Review usage before enabling
the trunk again.

### Step 4: View Outbound Trunk Credentials

After the outbound trunk is created, you can view its credentials by
selecting the key icon in the Credentials column on the Outbound Trunks page.

1. Go to **Voice > Outbound Trunks**.
2. Locate your outbound trunk and click the **key icon** in the **Credentials**
   column.

[![Selecting the credentials icon for the OpenSIPS outbound trunk](../../_images/open-outbound-trunk-credentials2.webp)](../../_images/open-outbound-trunk-credentials2.webp)


Opening the OpenSIPS outbound trunk credentials.

3. The trunk credentials will appear, showing the **Username** and
   **Password** (click the **eye icon** to reveal the password).
4. Copy and securely store the credentials, and choose an outbound endpoint
   from **Host(s)**. You will use them when you
   [configure outbound routing](#opensips-configure-outbound-routing).

[![Viewing the OpenSIPS outbound trunk credentials and hostnames](../../_images/outbound-trunk-credentials2.webp)](../../_images/outbound-trunk-credentials2.webp)


OpenSIPS outbound trunk credentials and hostnames.

The example uses `ams.eu.out.didww.com`. See
[Outbound SIP information](../../voice/outbound-trunks/outbound-sip-information.html) for regional
endpoints, DNS SRV failover, and BGP Anycast.

Important

The outbound digest authentication realm is `out.didww.com` for all
DIDWW outbound endpoints. Use this value in the `uac_auth` credential,
even when calls are sent to a regional hostname or `any.out.didww.com`.

Note

If an outbound password is exposed, regenerate it in the DIDWW User Panel.
Regenerating the password invalidates the previous value immediately.
Update the OpenSIPS credential and restart the proxy to use the new value.

---

## 3. Configure OpenSIPS

Configure OpenSIPS to use the DIDWW trunks created in
[Part 1](#opensips-configure-inbound-voice-trunk) and
[Part 2](#opensips-configure-outbound-voice-trunk). The script routes
calls between DIDWW and one user agent and authenticates outbound calls
without a database.

The examples use `/etc/opensips/opensips.cfg` and the module directory for
an x86-64 installation. They use UDP on port `5060`. Replace the example
addresses, caller ID, and uppercase credential placeholders with the values
for your deployment.

Note

For general information about the script and its routing model, see the
official [Types of routes](https://docs.opensips.org/manual/4-0/script-routes/)
and [Core Parameters](https://docs.opensips.org/manual/4-0/script-coreparameters/)
documentation.

### Before you begin

- [OpenSIPS 4.0](https://docs.opensips.org/manual/4-0/install-download/)
  is required.
- Install **opensips-auth-modules** to provide the
  [uac\_auth module](https://docs.opensips.org/manual/4-0/modules/uac_auth/)
  for outbound digest authentication.
- If you use a Dynamic Registration inbound trunk, install
  [OpenSIPS CLI](https://github.com/OpenSIPS/opensips-cli/blob/master/docs/INSTALLATION.md)
  to manage the registration.

### Step 1: Configure the OpenSIPS script

The same OpenSIPS script supports Static Endpoint and Dynamic Registration
trunks. Dynamic Registration additionally requires the registration in
[Step 3](#opensips-register-inbound).

The following blocks build `/etc/opensips/opensips.cfg` in order. Back up
the current file, then replace its contents with the global parameters,
module settings, and routing blocks below.

The examples use the following deployment values. Replace them consistently
before loading the configuration.

| Value in this guide | Replace with |
| --- | --- |
| `203.0.113.10` | The public address through which DIDWW can reach OpenSIPS. |
| `192.168.1.20` | The address of the user agent behind OpenSIPS. |
| `1000` | The user agent extension that receives incoming calls. |
| `442079460000` | A caller ID permitted by the outbound trunk's CLI settings. |
| `ams.eu.out.didww.com` | The outbound endpoint selected from the trunk's credentials. |
| `OUTBOUND_USERNAME` and `OUTBOUND_PASSWORD` | The outbound trunk credentials. |
| `INBOUND_USERNAME` and `INBOUND_PASSWORD` | The Dynamic Registration trunk credentials used when you [register the inbound trunk](#opensips-register-inbound). |

#### 1.1 Configure the listening socket and advertised address

Begin the file with the global parameters:

```
log_level=3
stderror_enabled=yes
syslog_enabled=no
udp_workers=4

socket=udp:0.0.0.0:5060
advertised_address="203.0.113.10"
```

Set `advertised_address` to the public address of the proxy or the NAT
device in front of it. This is normally the same address configured in the
[outbound trunk authentication settings](#opensips-configure-outbound-authentication).

The process writes logs to standard error at info level. Use this output
when [verifying calls](#opensips-verify-configuration).

Important

The advertised address must be reachable by DIDWW. OpenSIPS uses it in
`Via` and `Record-Route` headers. With the wildcard socket in this
example, leaving it unset can advertise `0.0.0.0` and prevent an
`ACK` from reaching the proxy. A call may connect and then disconnect
after approximately 30 seconds. Adding `rport` does not correct the
address used to route this request.

#### 1.2 Load the required modules and credentials

Add the module settings below the global parameters:

```
mpath="/usr/lib/x86_64-linux-gnu/opensips/modules/"

loadmodule "proto_udp.so"
loadmodule "signaling.so"
loadmodule "sl.so"
loadmodule "tm.so"
modparam("tm", "fr_timeout", 5)
modparam("tm", "fr_inv_timeout", 30)

loadmodule "rr.so"
modparam("rr", "append_fromtag", 1)

loadmodule "maxfwd.so"
loadmodule "sipmsgops.so"

loadmodule "mi_fifo.so"
modparam("mi_fifo", "fifo_name", "/tmp/opensips_fifo")
modparam("mi_fifo", "fifo_mode", 0666)

loadmodule "uac_auth.so"
modparam("uac_auth", "credential", "OUTBOUND_USERNAME:out.didww.com:OUTBOUND_PASSWORD")

loadmodule "uac.so"
modparam("uac", "restore_mode", "none")

loadmodule "uac_registrant.so"
modparam("uac_registrant", "hash_size", 2)
modparam("uac_registrant", "timer_interval", 30)
```

Set `mpath` to the module directory for your installation. The example
uses the x86-64 directory.

Replace `OUTBOUND_USERNAME` and `OUTBOUND_PASSWORD` with the
[outbound trunk credentials](#opensips-view-outbound-trunk-credentials).
Keep `out.didww.com` as the digest realm. Inbound registration credentials
are supplied separately in [Step 3](#opensips-register-inbound).

The FIFO path is the default used by `opensips-cli`. The registration
timer runs every 30 seconds. With the 60-second expiry in
[Step 3](#opensips-register-inbound), the proxy refreshes the
registration every 30 seconds to help keep the NAT mapping active.

Note

Keep the following settings from the tested configuration:

- `loadmodule "proto_udp.so"` is required in the tested build even
  though a separate module file is not present. Omitting it causes
  `no transport protocol loaded` at startup.
- `append_fromtag` must be `1` for `uac_auth()`, including when
  `restore_mode` is `none`.
- The tested build logs `ERROR:uac:mod_init: Can't load dlg API` while
  checking for the dialog API. It can continue without that API. Check
  subsequent output to confirm whether startup succeeded.

#### 1.3 Configure the DIDWW ACL

Open the main route with the request checks and DIDWW source-address match:

```
route {

    if (!mf_process_maxfwd_header(10)) {
        send_reply(483, "Too Many Hops");
        exit;
    }

    if (has_totag()) {
        if (is_method("ACK") && t_check_trans()) {
            t_relay();
            exit;
        }
        if (!loose_route()) {
            send_reply(404, "Not here");
            exit;
        }
        route(RELAY);
        exit;
    }

    if (is_method("CANCEL")) {
        if (t_check_trans())
            t_relay();
        exit;
    }

    if (is_method("OPTIONS")) {
        send_reply(200, "OK");
        exit;
    }

    if (!is_method("INVITE")) {
        send_reply(405, "Method Not Allowed");
        exit;
    }

    t_check_trans();
    record_route();

    if ($si =~ "^46\.19\.(2(08|09|1[0-5]))\." || $si =~ "^185\.238\.17[2-5]\.") {
```

The source-address expressions cover `46.19.208.0/21` and
`185.238.172.0/22`. These ranges contain the published DIDWW IPv4 signaling
addresses used by the tested configuration.

Important

Allow the DIDWW sources for the selected trunk type and failover
locations. With **Preferred Server** set to **Auto**, calls can arrive
from different DIDWW Points of Presence. See
[Technical Specifications](../../voice/inbound-trunks/technical-data/index.html) for the signaling
addresses and network requirements.

The example opens an IPv4 socket only. An IPv6 deployment requires additional
socket and source-address configuration.

#### 1.4 Configure inbound routing

Continue inside the DIDWW branch opened in the previous block:

```
        xlog("L_INFO", "inbound from carrier $si ruri=$ru from=$fu callid=$ci\n");
        $ru = "sip:1000@192.168.1.20:5060";
        route(RELAY);
        exit;
    }
```

Replace the URI with the extension, address, and port of the user agent
behind OpenSIPS. The `xlog` line records incoming requests for call testing.

Important

This example rewrites the Request-URI for every incoming call and sends
all DIDs to one destination. Keep the unconditional rewrite when using
this setup. Routing by called number requires a separate configuration
and confirmation of the Request-URI delivered by your trunk.

To serve several DIDs and route calls by the called number, use a **Static
Endpoint** trunk. DIDWW builds the Request-URI from **User Part of R-URI**, so
the number is included in the request line. Dynamic Registration trunks cannot
be distinguished by DIDWW source address because calls arrive from the same
DIDWW ranges. Separating them requires individual registration sockets and
routing based on the inbound socket, which is outside this guide.

#### 1.5 Configure outbound routing and digest authentication

Below the DIDWW branch, add the user-agent match and outbound routing:

```
    if ($si == "192.168.1.20") {
        add_local_rport();
        uac_replace_from("", "sip:442079460000@ams.eu.out.didww.com");
        $ru = "sip:" + $rU + "@ams.eu.out.didww.com";
        t_on_failure("CARRIER_AUTH");
        route(RELAY);
        exit;
    }

    send_reply(403, "Forbidden");
    exit;
}

route[RELAY] {
    if (!t_relay())
        sl_reply_error();
    exit;
}

failure_route[CARRIER_AUTH] {
    if (t_was_cancelled())
        exit;

    if (t_check_status("401|407")) {
        if (uac_auth()) {
            t_relay();
            exit;
        }
        xlog("L_ERR", "uac_auth() failed for callid=$ci\n");
    }
}
```

Replace `192.168.1.20` with the user agent's address. Replace
`442079460000` with the permitted caller ID and
`ams.eu.out.didww.com` with the selected outbound endpoint in both URIs.

The digest realm in the module settings remains `out.didww.com`
regardless of the outbound endpoint.

Note

- `add_local_rport()` adds `rport` to relayed requests so responses
  can return to the source port used by a NAT device.
- `uac_replace_from()` takes two arguments in OpenSIPS 4.0. The first
  is the display name, which is empty in this example.
- DIDWW can challenge an outbound `INVITE` with `401` and
  `WWW-Authenticate`. The failure route handles both `401` and
  `407` responses.

Important

DIDWW checks the caller ID written by `uac_replace_from()` against
**CLI Settings**. A successful digest exchange does not override caller ID
restrictions. With **On CLI Mismatch** set to **Reject Call**, an unlisted
caller ID causes the call to fail.

#### 1.6 Add rport to locally generated requests

Add a local route for requests generated by OpenSIPS, including registration:

```
local_route {
    add_local_rport();
}
```

The outbound route's `add_local_rport()` applies to relayed requests.
This local route also adds `rport` to `REGISTER` requests generated by
the proxy. Without it, a NAT device that changes the source port can prevent
registration responses from returning.

### Step 2: Load the configuration

Check that the configuration parses:

```
opensips -C -f /etc/opensips/opensips.cfg
```

Important

`config file ok, exiting...` confirms that the script parses. This
check does not initialize the modules. Start OpenSIPS and review the
startup output as well.

Start OpenSIPS in the foreground:

```
opensips -F -f /etc/opensips/opensips.cfg
```

Leave OpenSIPS running. If you use a Dynamic Registration trunk, open
another terminal and complete [Step 3](#opensips-register-inbound).

### Step 3: Register the inbound trunk

Complete this step for a **Dynamic Registration** trunk. Skip it for a
**Static Endpoint** trunk.

Submit the registration through the management interface:

```
opensips-cli -x mi uac_registrant:upsert \
    aor="sip:INBOUND_USERNAME@sip.didww.com" \
    contact="sip:INBOUND_USERNAME@203.0.113.10:5060" \
    registrar="sip:sip.didww.com" \
    proxy="" \
    third_party_registrant="" \
    username="INBOUND_USERNAME" \
    password="INBOUND_PASSWORD" \
    binding_params="" \
    expiry=60 \
    forced_socket="" \
    cluster_shtag="" \
    state=0
```

Replace the username and password with the
[inbound trunk credentials](#opensips-copy-inbound-trunk-credentials).
Use the selected registration endpoint for the address-of-record domain and
registrar. Set the contact address to the public address and port through
which DIDWW can reach OpenSIPS.

All 12 parameters are required, including those with empty values. Missing
parameters return `Invalid params (Too few or too many parameters)`.
Incorrect parameter names return
`Invalid params (Named parameters do not match)`.

Important

An `OK` response confirms that the registration record was accepted.
Run `opensips-cli -x mi uac_registrant:list` and check the `state`
field to confirm registration:

- `REGISTERED_STATE` indicates a successful registration.
- `NOT_REGISTERED_STATE` can appear until the registration timer
  processes the record, which may take up to 30 seconds.
- `WRONG_CREDENTIALS_STATE` indicates rejected credentials.

The registration is supplied at runtime through the management interface,
so this setup does not require a database. The short expiry and registration
timer help maintain the inbound NAT mapping.

Important

The registration record is created at runtime and is not stored in a
database. Submit the registration command again after restarting OpenSIPS.

### Step 4: Verify the configuration

| Check | Action | Expected result |
| --- | --- | --- |
| Listening socket | Review the startup output. | A `Listening on` block includes `udp: 0.0.0.0 [0.0.0.0]:5060`. |
| Dynamic Registration | Run `opensips-cli -x mi uac_registrant:list`. | The `state` field shows `REGISTERED_STATE`. |
| Inbound calling | Call a DID assigned to the inbound trunk. | The process output includes the inbound `xlog` message from [inbound routing](#opensips-configure-inbound-routing). |
| Outbound calling | Place a call from the user agent. | The SIP trace shows a `401` challenge, a second `INVITE` with authentication, and a `200 OK` response. |

Check the user agent as well to confirm that incoming calls are received and
audio works in both directions.

#### Common issues

Calls disconnect after approximately 30 seconds

Check `advertised_address`. An unreachable address in `Record-Route`
prevents DIDWW from delivering the `ACK`. The user agent retransmits
`200 OK` until the call times out. See
[listening socket and advertised address](#opensips-configure-socket).

An inbound call does not reach the user agent

Check for the inbound `xlog` message. If it is missing, confirm that
the request reached OpenSIPS and that its source matched the DIDWW ACL.
For Dynamic Registration, check the registration state as well.

If the message is present, check the destination URI and the user agent's
reachability. Keep the unconditional Request-URI rewrite from
[inbound routing](#opensips-configure-inbound-routing).

OpenSIPS rejects inbound calls with 403 Forbidden

Compare the request's `$si` source address with the
[DIDWW ACL](#opensips-configure-acl). Check the published addresses
for the trunk type and its failover locations.

The inbound trunk does not register

Allow up to 30 seconds for the registration timer to process the record.
If registration still fails, check the state:

- `REGISTER_TIMEOUT_STATE` indicates that no response was received.
  Check the network path and the
  [local route](#opensips-configure-local-route) used to add
  `rport` behind NAT.
- `WRONG_CREDENTIALS_STATE` indicates rejected credentials.
- `REGISTRAR_ERROR_STATE` indicates another error from the registrar.

Outbound calls fail after successful authentication

Check the caller ID set by `uac_replace_from()` against **Allowed
CLI(s)** and **On CLI Mismatch**. Then check **Destination Dialing
Settings** and the trunk's **Status**. Reaching the 24-hour limit
automatically disables the trunk.

OpenSIPS does not answer an outbound 401 challenge

Check that the outbound credential uses `out.didww.com` as its realm.
A credential stored under a regional hostname will not match the
challenge. The failure route logs `uac_auth() failed` when
authentication cannot be completed. See
[module settings and credentials](#opensips-load-modules).

Outbound calls receive no response behind NAT

Confirm that the outbound branch includes `add_local_rport()`.
This allows responses to return to the source port used by NAT. See
[outbound routing](#opensips-configure-outbound-routing).

OpenSIPS reports no transport protocol loaded

Keep `loadmodule "proto_udp.so"` in the
[module settings](#opensips-load-modules). It is required by the
tested build even though a separate module file is not present.

OpenSIPS reports an append\_fromtag initialization error

Keep `modparam("rr", "append_fromtag", 1)` in the
[module settings](#opensips-load-modules). The tested configuration
requires it when using `uac_auth()`, including with `restore_mode`
set to `none`.

OpenSIPS logs Can't load dlg API at startup

The tested build can continue after
`ERROR:uac:mod_init: Can't load dlg API`. Review the following log
messages and confirm that the proxy is listening. Do not treat this
message alone as proof that startup failed.

For more information about OpenSIPS scripting, see the official
[Types of routes](https://docs.opensips.org/manual/4-0/script-routes/) and
[Core Parameters](https://docs.opensips.org/manual/4-0/script-coreparameters/)
documentation.

On this page
