Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

issue about "usrloc expiring location record from different registrar after startup" #601

Closed
hd16861686 opened this issue Aug 14, 2015 · 5 comments
Assignees

Comments

@hd16861686
Copy link

Hello, how are you?
I got the followed mail from below link,
http://article.gmane.org/gmane.comp.voip.opensips.user/8242/match=database+synchronization+delete+wrong+contact
But I don't understand why non db-only modes don't support location table sharing.
I met the same scene issue as described in below mail but in Write-Back scheme of db-mode.
According to "it is only written (cache flushed into DB) and never read (only at startup) ", actually we can read location table through avp_db_query in script in non db-only modes, and the only issue is when opensips 1 restart and load all online user from location table and after a while opensips 1 find some users expired which is regisgtered in opensips 2, but then opensips 1 delete these users even these users is not belong to opensips 1, that's the issue.
But I think this issue can be solved by modifying the code.
for example in opensips 2.1 in wb_timer function of usrloc module, the deleting user from db logic below, besides the condition "st_expired_ucontact(t) == 1", we can also add one more condition like "t->sock != 0", so that those expired users not belong to opensips node will not be deleted from db and the issue solved.

Is this right ? or if i missing something?

                     /* Should we remove the contact from the database ? */
        if (st_expired_ucontact(t) == 1) {
            if (db_delete_ucontact(t) < 0) {
                LM_ERR("failed to delete contact from the database\n");
                /* do not delete from memory now - if we do, we'll get
                 * a stuck record in DB. Future registrations will not be
                 * able to get inserted due to index collision */
                continue;
            }
        }

From: Bogdan-Andrei Iancu bogdan@...
Subject: Re: usrloc expiring location record from different registrar after startup
Newsgroups: gmane.comp.voip.opensips.user
Date: 2009-12-02 09:44:47 GMT (5 years, 36 weeks, 2 days, 15 hours and 6 minutes ago)
Hi Henk,

In non db-only modes, the primary storage is the mem cache - the DB is
used only as a secondary storage support (for persistence across
reboots) and it is only written (cache flushed into DB) and never read
(only at startup) - this is why you cannot share a location table via 2
servers.

Let me know if you experience the same problem while using the db-only mode.

Regards,
Bogdan

Henk Hesselink wrote:

Hi Bogdan,

I think the problem comes from using write-through mode, I'll see if it
goes away with db-only. It wasn't clear to me from the documentation
that only db-only mode is supported with a shared DB.

Anyway, in case there is more going on, enclosed are the location table
entries for the UAC (name testtcp30001, the 'tcp' means nothing - it
uses UDP) and the relevant DB queries. Registrar A is 79.171.196.85,
registrar B is 79.171.192.85. All servers are synchronized with NTP.

  • After T1 there is a single record
  • after T2 also
  • after T3 the record is gone

The Tx.db files all have 2 lines: the location table before and after Tx.

Regards,

Henk

Bogdan-Andrei Iancu wrote:

Hi Henk,

Reviewing your scenario (in db_only mode):

T1 - registrar A restarts, finds UA registration inserted by registrar B
with expiry time T3, prints "non-local socket ... ignoring"
message
T2 - UA registers again with registrar B, sets expiry time to after T3
T3 - registrar A deletes record for UA

please check:

  • after T1, you have a single record for user in the location table
    (inserted by A)
  • after T2, do you have 2 records for the user (with different contacts)
    or the existing one is updated ?
  • after T3 - I understand all the records for the user are removed,
    right ?

can you make a capture of the sql queries on the mysql server (to see
what queries - location related- are run by each server).

I'm asking for all this because, following the code, I cannot "see" the
behaviour you describe - maybe I miss something or maybe there is a bug
somewhere.

Regarding the other db modes, note they do not work (by design) with
shared dbs.

May be a useless note, but take care to have sync times on both servers
(A and B) !

Regards,
Bogdan

Henk Hesselink wrote:

Hi Bogdan,

Did you make the patch?

Regards,

Henk

Bogdan-Andrei Iancu wrote:

Hi Henk,

Yes, I'm aware of this issue with the db_only mode - I will prepare a
fixing patch for monday, so if you could test it, it will be great!

Thanks and regards,
Bogdan

Henk Hesselink wrote:

Hi all,

We have several OpenSIPS registrars writing to one location table.
When one of the registrars restarts it logs a lot of the following:

WARNING:usrloc:dbrow2info: non-local socketudp:XXXX:5060...ignoring

which I believe we can ignore. But it then deletes all those
non-local
entries at the 'expires' time that was in the database at the time of
the restart. So:

T1 - registrar A restarts, finds UA registration inserted by
registrar B
with expiry time T3, prints "non-local socket ...
ignoring" message
T2 - UA registers again with registrar B, sets expiry time to
after T3
T3 - registrar A deletes record for UA

After T3 the registration for UA never reappears because its register
requests cause registrar B to do an update for a non-existent record.
This seems wrong, or am I missing something?

Thanks,

Henk

Bogdan-Andrei Iancu
www.voice-system.ro

@bogdan-iancu bogdan-iancu self-assigned this Aug 17, 2015
@bogdan-iancu
Copy link
Member

Hi @hd16861686, In my email I explained how the current DB modes do work for the usrloc module (how they work per design).
If you want to do sharing via DB, then, of course, the DB must be the primary storage.

What exactly are you looking for ?

@hd16861686
Copy link
Author

Hi bogdan, I'm so excited to receive your reply!
one side I want to get the statistics about usrloc but db_only mode disable it, from this I can only use non db_only mode..
and another side I want to sharing user register info via DB but not the primary storage, so that when a call coming and opensips can not find callee in local mem, then I can make a try to query callee in DB and get callee's real registered opensips node and route this invite to it.
but in my test I found problem that in non db_only mode opensips remove the expired users from db without considering whether the deleted users registered in it.
So I try to solve this problem, my solution is to make one more judgment before deleting the expired users, like "t->sock != 0" because if the user registered in local then its socket info in mem will be null, to check if the user is not registered in local then opensips remove this user from mem and do not remove it from DB. can you help me to check if my solution is OK or not? or I missing something?

@jalung
Copy link
Contributor

jalung commented Aug 20, 2015

I'm not understanding why it is a problem if Opensips deletes expired usrloc records, wherever they may be. This may be an issue for you, but it is problematic sharing location table among multiple opensips instances on other levels. Most of all, lookups will not work properly because a user might have NAT open with another registrar. I'm not advocating any change in the code though, because there are ways around it, they are just complex.

My suggestion is a bit unconventional and works around the problem, by not using the lookup function. Scenario: Registrations are not being forwarded and a user may register wherever they want using the same credentilas based on the max allowed contacts limit. Using mongo DB for user location storage. Load balancing using DNSSRV. User is registered on four servers and receives a call.

..
save("location") #on all servers using DB-Only
..

call comes in:

Query the location table for contacts, bflags and socket
Manually append the branches setting the $ruri or both $ruri and $du, while manually setting the branch flags and dialog variables for callee here or adding custom record route variable for the remote AOR's.

Manually set the bflags for callee on the receiving remote server based on the custom rr header. Use dialog variables to remember them, then route it out, again no lookup().

For the answered branch, use dialog variables to set bflags again for caller to callee on each reinvite (video request for example during call).

On reboot, the DB will always be current based on the max contacts.

This is not a simple setup though and requires many constructs depending on who the message is from and the type of rtp proxy being used, what routes and flags to be set.

As for the statistics, you might be able to use mode 1 (Write-Through Scheme) with the method above.
Not using the lookup function you loose the method filtering feature and will need to do your own. Opensips is still flexible enough to use the lookup() with the above but you need to issue save twice.

save("server1location")
save("commonlocation")

query the commonlocation for the users, do the lookup againtst serverXlocation if found in common and then append branches for the remote contacts found elsewhere. This second method works nicely without worrying about the bflags etc., But there are issues when a user registers with another registrar and did not unregister from the previous.

@stale
Copy link

stale bot commented Jul 3, 2019

Any updates here? No progress has been made in the last 15 days, marking as stale. Will close this issue if no further updates are made in the next 30 days.

@stale stale bot added the stale label Jul 3, 2019
@bogdan-iancu
Copy link
Member

This topic is outdated since the clustering support was added for usrloc module (the reported issue were side effects of an forced usage of the db-modes in usrloc).
First migrate to 2.4 and clustered usrloc and if you still have questions, open a new ticket.

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

No branches or pull requests

4 participants