bferreirq created an issue (kamailio/kamailio#4565)

### Description

When using `publ_cache = 2` (memory-only mode) with the `pua_json` module to 
publish MWI (message-summary) events, multiple presentity entries with the 
**same etag** accumulate in memory instead of being replaced.

This causes **inconsistent NOTIFY messages** to be sent to subscribers: 
sometimes the most recent state (correct), sometimes an obsolete state 
(incorrect).

According to RFC 3903, when a PUBLISH with an existing etag is received, it 
should **replace** the previous entry, not create a duplicate.

### Troubleshooting

#### Reproduction

1. Configure Kamailio with:
   - `publ_cache = 2` (memory-only mode)
   - `subs_db_mode = 0` (memory-only mode)
   - External application publishes MWI updates via HTTP to `pua_json_publish()`

2. Publish multiple MWI updates for the same user over several days:
   ```json
   POST /sip_not/ HTTP/1.1
   {
     "Event-Package": "message-summary",
     "From": "sip:[email protected]",
     "Messages-New": 3,
     "Messages-Saved": 0,
     "Expires": "63072000",
     "Call-ID": "fake_call_id"
   }
   ```

3. Later, publish a new state:
   ```json
   {
     "Messages-New": 0,
     "Messages-Saved": 0,
     "Call-ID": "fake_call_id"
   }
   ```

4. Check the cache:
   ```bash
   kamcmd presence.presentity_show full user domain.com
   ```

**Result**: Multiple entries with the same `etag: fake_call_id` coexist instead 
of the newer one replacing the older ones.

#### Debugging Data

Cache inspection shows 3 duplicate entries for the same user with identical 
etag:

```
Entry 1 (Most recent):
  user: user
  domain: domain.com
  event: message-summary
  etag: fake_call_id
  expires: 1832235420
  received_time: 1769163420  (Jan 23, 2026 11:03)
  priority: 0
  body: Voice-Message: 0/0 (0/0)
  hashid: -883060685

Entry 2 (Obsolete):
  user: user
  domain: domain.com
  event: message-summary
  etag: fake_call_id
  expires: 1831959900
  received_time: 1768887900  (Jan 20, 2026 04:05)
  priority: 0
  body: Voice-Message: 4/0 (0/0)
  hashid: -883060685

Entry 3 (Obsolete):
  user: user
  domain: domain.com
  event: message-summary
  etag: fake_call_id
  expires: 1831908632
  received_time: 1768836632  (Jan 19, 2026 14:17)
  priority: 0
  body: Voice-Message: 3/0 (0/0)
  hashid: -883060685
```

All three entries share:
- Same `etag: fake_call_id`
- Same `hashid: -883060685`
- Different `received_time` and body content

#### Log Messages

No errors in logs. The publications are accepted successfully, but old entries 
are not removed.

#### SIP Traffic

When a SUBSCRIBE is received, the NOTIFY sometimes contains **obsolete values** 
from older cache entries instead of the most recent one

Example NOTIFY with obsolete value:
```
NOTIFY sip:[email protected] SIP/2.0
Event: message-summary
Subscription-State: terminated;reason=timeout
Content-Type: application/simple-message-summary

Messages-Waiting: yes
Message-Account: sip:[email protected]
Voice-Message: 3/0 (0/0)
```

### Possible Solutions

**Workarounds attempted:**
- ✅ `kamcmd presence.cleanup` → No effect (entries have future expires)
- ✅ `kamcmd presence.refreshWatchers` → No effect (entries not removed)
- ❌ No RPC command found to remove specific presentity entries

**Only solution found:** Restart Kamailio (clears memory cache entirely).

**Questions:**

1. **Is this a bug?** Should presentities with the same etag be replaced 
instead of accumulated?

2. **Selection logic**: With `retrieve_order = 0` (default), documentation 
states "presentity records are retrieved by received_time order". When multiple 
entries exist:
   - Which one is selected for NOTIFY?
   - Is it guaranteed to be the most recent (highest received_time)?
   - Why do we sometimes get obsolete entries in NOTIFY?

3. **Cleanup**: Is there any RPC command to:
   - Remove a specific presentity entry by `ruid`?
   - Force removal of obsolete entries with the same etag?
   - Flush presentity cache for a specific user without restarting?

4. **Configuration recommendation**: Should we use `publ_cache = 0` when an 
external application publishes via `pua_json`?

### Additional Information

**Kamailio Version**:
```
version: kamailio 5.7.3 (x86_64/linux) 
flags: USE_TCP, USE_TLS, USE_SCTP, TLS_HOOKS, USE_RAW_SOCKS, DISABLE_NAGLE, 
USE_MCAST, DNS_IP_HACK, SHM_MMAP, PKG_MALLOC, MEM_JOIN_FREE, Q_MALLOC, 
F_MALLOC, TLSF_MALLOC, DBG_SR_MEMORY, USE_FUTEX, FAST_LOCK-ADAPTIVE_WAIT, 
USE_DNS_CACHE, USE_DNS_FAILOVER, USE_NAPTR, USE_DST_BLOCKLIST, HAVE_RESOLV_RES, 
TLS_PTHREAD_MUTEX_SHARED
ADAPTIVE_WAIT_LOOPS 1024, MAX_RECV_BUFFER_SIZE 262144, MAX_URI_SIZE 1024, 
BUF_SIZE 65535, DEFAULT PKG_SIZE 8MB
poll method support: poll, epoll_lt, epoll_et, sigio_rt, select.
```

**Operating System**:
```
Debian GNU/Linux 10 (buster)
Linux 4.19.0-21-amd64 #1 SMP Debian 4.19.249-2 (2022-06-30) x86_64 GNU/Linux
```

**Modules loaded**:
```
kamailio-presence-modules:amd64    5.7.3+bpo10
kamailio-json-modules:amd64        5.7.3+bpo10
```

**Configuration excerpt**:
```cfg
modparam("presence", "subs_db_mode", 0)
modparam("presence", "publ_cache", 2)
modparam("presence", "expires_offset", 10)
modparam("presence", "max_expires", 86400)
modparam("presence", "min_expires", 30)
modparam("presence", "pres_htable_size", 20)
modparam("presence", "subs_htable_size", 20)
modparam("presence_mwi", "default_expires", 3600)

event_route[xhttp:request] {
    xhttp_reply("200", "OK", "text/html","<html><body>OK</body></html>");
    $var(x) = pua_json_publish($rb);
}
```

-- 
Reply to this email directly or view it on GitHub:
https://github.com/kamailio/kamailio/issues/4565
You are receiving this because you are subscribed to this thread.

Message ID: <kamailio/kamailio/issues/[email protected]>
_______________________________________________
Kamailio - Development Mailing List -- [email protected]
To unsubscribe send an email to [email protected]
Important: keep the mailing list in the recipients, do not reply only to the 
sender!

Reply via email to