Follow up the DNS-based SGW/PGW selection introduced by #4693 and
harden several fallback, asynchronous completion, cache, resolver,
and compatibility paths found during review and testing.
A DNS failure must never prevent an attach when a statically
configured gateway remains available. Preserve the SGW serving the
UE when a DNS resolution is created and restore it whenever a later
DNS-based SGW selection cannot complete.
This is required because a previous Create Session Request attempt
may already have switched the UE to a DNS-discovered SGW. If that
request times out and the next DNS candidate cannot be resolved, simply
returning from apply_sgw() leaves the UE attached to the failed DNS SGW
and causes subsequent CSR attempts to continue using it instead of the
original fallback SGW.
Restore the pre-DNS SGW when:
* the SGW DNS leg ends in fallback after an earlier SGW switch
* mme_sgw_add() cannot create the selected SGW node
* ogs_gtp_connect() cannot connect the selected SGW
* the deferred Create Session Request cannot be built or committed
The fallback pointer records the SGW currently serving the UE when the
resolution is created rather than assuming it is always statically
configured. Successfully connected SGW nodes are retained for the
process lifetime, so the stored pointer remains valid.
The PGW path does not require the same state restoration. When PGW DNS
selection falls back, mme_dns_sess_pgw_addr() returns NULL and the S11
Create Session Request builder selects the statically configured PGW
again on each attempt.
Harden deferred CSR completion handling.
post_resolved() runs on the MME main thread, which is also responsible
for draining the application event queue. ogs_queue_push() can block
indefinitely when that queue is full, causing a self-deadlock because
the blocked producer is also the only consumer.
Use ogs_queue_trypush() instead. When it returns OGS_RETRY, return the
resolution to PENDING and restart its guard timer. The DNS legs are
already complete, so the guard callback simply attempts to post the
completed result again. Do not retry when the queue has been terminated
during shutdown.
Do not move a resolution to CONSUMED or increment csr_attempts until
the deferred CSR transaction has been successfully built and committed.
The GTP timeout retry path uses CONSUMED as its eligibility condition,
so marking an unsent request as consumed leaves meaningless retry state.
If local CSR creation fails, restore the pre-DNS SGW first and then
remove the resolution. This prevents a subsequent NAS retry from
capturing the failed DNS SGW as its new fallback and prevents a stale
CONSUMED resolution from incorrectly short-circuiting the new request
to SEND_NOW.
Document that OGS_OK from mme_gtp_send_create_session_request() may
mean that the request was deferred for DNS selection and does not
guarantee that a GTP transaction exists when the function returns.
Fix an MME event-loop hang caused by unusable SRV answers.
An SRV record whose target is "." indicates that the service is not
available. mme_dns_candidate_apply_srv() previously left the candidate
unchanged in this case. leg_advance() then repeatedly read the same
cached SRV answer without advancing the candidate cursor, hanging the
MME event loop.
Make mme_dns_candidate_apply_srv() return whether it found a usable
target. Skip the candidate when all SRV targets are empty or ".", while
leaving the candidate unchanged for callers that need to inspect the
failure.
Add unit and DNS integration coverage for this case. Extend the test DNS
server to encode "." as the DNS root label and verify that the MME skips
the unusable SRV candidate and falls back instead of hanging.
Bound the MME DNS cache to prevent expired entries from accumulating
indefinitely across many TAC and APN names.
When inserting a new key at capacity:
* remove expired entries
* if the cache remains full, evict entries closest to expiry
* do not make room when replacing an existing key, which would otherwise
evict an unrelated entry on every refresh at capacity
Disable the c-ares internal query cache when the installed c-ares
version provides ARES_OPT_QUERY_CACHE. c-ares 1.31 and later enable an
internal cache by default, which can continue answering a query after
the MME's own cache entry has expired and silently override the
operator-configured dns.cache_ttl. Set qcache_max_ttl to zero so the
MME cache remains authoritative.
Retain compatibility with both older distribution versions of c-ares
and newer releases that deprecate the legacy query and reply parsing
APIs. Define CARES_NO_DEPRECATED before including ares.h to suppress
the newer deprecation attributes without raising the minimum supported
c-ares version.
Validate configured resolver addresses before initializing c-ares.
Require each dns.server address to be a bare IPv4 or IPv6 literal.
Reject hostnames, malformed addresses, bracketed addresses, scope
suffixes, and IPv6 link-local addresses, which require interface scope
handling that is not supported by the MME configuration.
Format resolver entries as:
* IPv4: address:port
* IPv6: [address]:port
The brackets are required by the c-ares server CSV format. Without
them, a value such as 2001:db8::53:53 is accepted as a different valid
IPv6 address using the default DNS port, causing queries to be sent
silently to the wrong resolver.
Build and validate the server CSV before c-ares initialization so
configuration failures do not require partially initialized channel or
library cleanup. The fixed CSV buffer remains safe because inet_pton()
guarantees that accepted addresses fit the maximum IPv4 or IPv6 literal
length.
Explicitly initialize mme_sess_t::dns_id to OGS_INVALID_POOL_ID instead
of relying on the current value of the pool allocator's zero-filled
memory.
Update the sample configuration and documentation to describe the
current DNS-selection limitations:
* roaming PGW lookup currently builds the APN-FQDN from the serving PLMN
rather than deriving the home-PLMN APN-OI
* only A records are used for discovered gateways
* SRV weights are ignored
* non-terminal NAPTR records are not followed
* DNS-discovered SGW nodes are retained for the process lifetime
* resolver addresses must be bare IPv4 or IPv6 literals
* link-local IPv6 resolvers are not supported
Add the c-ares development dependency to Debian, Ubuntu, Fedora, Alpine,
CentOS, macOS, and FreeBSD build instructions and container images, and
add the c-ares MIT license notice.
Also link the DNS selection unit tests against libmme directly so they
exercise the same mme-dns-select implementation built for the MME.
MongoDB is required by database-backed components such as HSS/PCRF
and PCF/UDR, but it does not need to be installed locally when an
external MongoDB server is used.
Move the MongoDB package relationship from Depends to Recommends for
the affected Debian packages, so the default installation still pulls
MongoDB in while allowing users to opt out with --no-install-recommends.
Update the documentation to clarify which components use MongoDB and
explain that the MongoDB installation step can be skipped when using an
external database.
* AMF dynamic PLMNs via APIREST
* add new feature now we can register ues when plmn is deleted
* add documentation for use the API AMF-OAM
* update tutorial 08
* fix memory not freed
fix memory not freed
fix memory not freed
* improve releases ues of plmn
The previous key downloaded from `download.opensuse.org` was expired
(EXPKEYSIG FE7F42F276CEE0E6), causing `apt update` to fail when following
the Debian quickstart instructions.
This patch replaces the deprecated key URLs with valid signing key
download locations from build.opensuse.org and obs.osmocom.org.
Issues: #4175
This update adds a comprehensive description of the Home Routed Roaming
functionality, enhances the architecture section and message
flow diagrams to illustrate the new routing process, and provides
clear configuration examples and command‑line snippets to assist
users with setup.
Previously, policies were configured via YAML files without MongoDB.
This update enhances the YAML approach by adding the 'supi_range' key to
filter policies based on UE SUPI ranges. When both 'supi_range' and
'plmn_id' are provided, both conditions must be met.
Note that PLMN-ID filtering will be deprecated in a future release.
- Upgraded libraries to 4.5 to address compile error issues with CXX11 support
- Change the default version of FreeBSD Vagrant to 14.1-STABLE
- FreeBSD Platform documentation also changed to 14.x version
A friend in the community was trying to connect an SMF made by another
manufacturer with an SBI interface and found a big problem with Open5GS.
All of the code in the part that generates the Resource URI
from HTTP.location is invalid.
For example, suppose we create a Resource URI with SMContext as below.
{apiRoot}/nsmf-pdusession/<apiVersion>/sm-contexts/{smContextRef}
In this case, Open5GS extracted the {smContextRef} part of the HTTP.location
and appended it to the beginning
{apiRoot}/nsmf-pdusession/<apiVersion>/sm-contexts/.
This implementation may not work properly if the apiRoot changes.
Consider a different port number as shown below.
<HTTP.location>
127.0.0.4:9999/nsmf-pdusession/v1/sm-contexts/1
The SMF may send an apiRoot to the AMF with a changed port number,
in which case the AMF must honor it.
Therefore, instead of extracting only the smContextRef from HTTP.location,
we modified it to use the whole thing to create a Resource URI.
We modified all NFs that use HTTP.location in the same way, not just SMFs.
If eg. PCRF or AAA diameter link is not yet ready (eg. PCRF crashed),
and a client sends a CreateSessionRequest announcing its ow F-TEID,
then open5gs-smfd answers with Create Session Response Cause=
"Remote peer not responding", but it is not setting the received F-TEID
in the header of the response, instead it sends with TEI=0.
As a result, the peer cannot match the CreateSessionResponse,
and needs to rely on its own timeout timer to figure out
that specific request failed.
To address this issue, I modified the GTP Response message to check
the Sender F-TEID and send it accordingly, setting the destination TEID
to the value of the Sender F-TEID.
I've made this modification only for SMF, but MME and SGW-C have not done so;
if you need to, you can work from the examples in SMF.
Similarly, the same situation can happen with PFCP. If anyone needs to do this
in the future, I think you can work on it this way.
1. According to ETSI TS 129 118 4.1, if the Network Access Mode (NAM) is set
to "Packet only," no SGs association should be established.
2. If the NAM is set to "Packet and Circuit," and the SGs association is
rejected by the CS core, this rejection should only impact
the SGs association itself and not result in a UE attach rejection
for a UE with a valid HSS account.
APER encoding fails when using the asn_uint642INTEGER function on a 32-bit machine as shown below.
```C
asn_uint642INTEGER(AMF_UE_NGAP_ID, 0xffffffff);
...
aper_encode_to_buffer(...)
```
INTEGER APER encode/decode functions seem to be operating internally with long variables instead of intmax_t.
That is probably the reason of the failure.
@v0-e fixed this issues in the mouse07410/asn1c pull request.
https://github.com/mouse07410/asn1c/pull/176https://github.com/mouse07410/asn1c/pull/177
* Update 03-VoLTE-dockerized.md
adding "-" in docker-compose commands and added filename t the docker-compose command
* Adding up command to docker-compose
Need to bring docker images up to run the Open5Gs system.
NAS, GTP, PFCP, SBI, all except S1AP/NGAP use x1000 multiplier for Kbps, Mbps, Gbps ... etc.
From now on in WebUI all units also use a multiplier of x1000.