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

[FEATURE] uac_registrant match URI to Contact header partially #2557

Open
vasilevalex opened this issue Jun 24, 2021 · 8 comments · May be fixed by #2558
Open

[FEATURE] uac_registrant match URI to Contact header partially #2557

vasilevalex opened this issue Jun 24, 2021 · 8 comments · May be fixed by #2558
Assignees
Milestone

Comments

@vasilevalex
Copy link
Contributor

Is your feature request related to a problem? Please describe.

If we have a lot of external registrations, let's say 100000, we can distribute them through several, for example 10 servers. Put accounts to the DB, connect all OpenSIPS servers to this DB, create cluster of servers.Create for example 10 different tags for cluster, so each server will process only 10% of total amount of registrations. And if one server dies, just move its' tag to another server. It will increase load twice, but everything will be reliable.
Very simple scheme. Just every server substitutes its' IP-address instead of the hostname in "binding_URI" when sending outgoing REGISTER:

local_route {
	if (is_method("REGISTER") && $(ct.fields(uri){uri.host}) == "local.opensips") {
		$var(subst) = "/local.opensips/$socket_out(ip):$socket_out(port)/g";
		$var(new_contact) = $(ct{re.subst,$var(subst)});
		remove_hf("Contact");
		append_hf("Contact: $var(new_contact)\r\n");
	}
}

Everything works, except one problem. Expiration time for registration, provided in "200 OK" from external system is not applied to OpenSIPS. Because module uac_registrant compares URI from Contact header from "200 OK" to the full value of "binding_URI". They are different, as we are changing Contact in outgoing REGISTER.
It would be nice to have parameter for matching contact URI, to choose what parts of URI must match. And just ignore the rest.

Describe the solution you'd like
Parameter to uac_registrant module to choose what parts of URI use to match.

Implementation
I'll send PR

Describe alternatives you've considered
Store in reg_record->contact not just raw value of binding_URI, but dynamic value with host depending on sending socket.

@github-actions
Copy link

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.

@github-actions github-actions bot added the stale label Jul 17, 2021
@stale stale bot removed the stale label Jul 20, 2021
@bogdan-iancu bogdan-iancu added this to the 3.3 milestone Jul 20, 2021
@bogdan-iancu
Copy link
Member

@vasilevalex , IMHO, the contact based matching is wrong, the module should rely on a transaction level matching (for matching the reply against the sent request and extract the expired value).

@bogdan-iancu
Copy link
Member

oh, hold you, by contact matching you mean identifying its own contact from the list of returned contacts, right ?

@vasilevalex
Copy link
Contributor Author

@bogdan-iancu Yes, it's about matching contact from "200 OK" reply. And now it is done by strict comparing with value of binding_URI column. And it's not flexible at all. But PR is not perfect, because I just took existing compare_uris function and added another one compare_uris_parts modified for this purpose. It worth to have one function, but I didn't want to break things...

@bogdan-iancu
Copy link
Member

OK, I see it. Maybe we can solve this (somehow) by using the recent "tag" of the interfaces. So, in the uac_registrant binding URI you use the "tag" of the interface and we need to trick the matching function to use it , when comparing the host part of the URI......just a rough, superficial idea :)

@vasilevalex
Copy link
Contributor Author

If the host has active "tag" for the registration entry, it can generate Contact header with hostname or ip-address, belonging to this host. That part I did in config script in local_route using $socket_out(ip):$socket_out(port).
And then match Contact from reply can ignore host part of uri and compare it with hosts listening sockets. Something like this, but I don't know if it covers all possible use cases.

@bogdan-iancu
Copy link
Member

@vasilevalex , checking the module I see that the binding_uri column may be empty - in this case the module will automatically build the CT URI based on the forced_socket field (and if I'm not wrong, you can fill in a socket tag here).
So you can share the uac_registrant table across different OpenSIPS instances using the empty binding URI, but forcing a socket via its tag. And in this case the 200 OK contact should be recognized by each individual OpenSIPS instance. Do you think this will solve your problem ?

@bogdan-iancu bogdan-iancu self-assigned this Apr 18, 2022
@vasilevalex
Copy link
Contributor Author

Hi @bogdan-iancu,
According to

LM_ERR("columns [%.*s] or/and [%.*s] or/and [%.*s]"

and
/* Get the binding (manadatory parameter) */

binding_URI is mandatory parameter. And if it's empty the record is just skipped.
But even if it would be automatically generated, forced_socket is perfect for use, but what to do with "user" part of URI? It is usually phone number, as we want to receive calls to the numbers. But in real life registration data (username) and contact header URI (username) are different, so anyway we need to have some unique "user" part of URI to create final "binding URI".

I have setup with my patch in production for many months. But as you said before, the right way is to use active tag for every record to generate URI, when sending outgoing registration. And it of course can be conditional (another module parameter) to keep compatibility.

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

Successfully merging a pull request may close this issue.

2 participants