summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrédéric Brière <fbriere@fbriere.net>2019-07-03 15:18:56 -0400
committerFrédéric Brière <fbriere@fbriere.net>2019-07-03 16:21:09 -0400
commitcedd7a19a4fb415031b97592129214d2163563aa (patch)
tree2c53c29f96a0fc490c2baef1bfeaecee35a37de2
parent05082ae12051821b1d969e6672d9e4e5afe1bc07 (diff)
downloadtwinkle-cedd7a19a4fb415031b97592129214d2163563aa.tar
twinkle-cedd7a19a4fb415031b97592129214d2163563aa.tar.gz
twinkle-cedd7a19a4fb415031b97592129214d2163563aa.tar.lz
twinkle-cedd7a19a4fb415031b97592129214d2163563aa.tar.xz
twinkle-cedd7a19a4fb415031b97592129214d2163563aa.zip
Prevent recursive locking of phone_users_mtx in add_phone_user()
When encountering two users with the same contact name, attempting to differentiate them using USER_HOST(), a.k.a. get_ip_sip(), would result in EDEADLK since phone_users_mtx was already locked by add_phone_user(). Closes #88
-rw-r--r--src/phone.cpp8
-rw-r--r--src/phone.h2
2 files changed, 8 insertions, 2 deletions
diff --git a/src/phone.cpp b/src/phone.cpp
index 16abc38..5f2ac2d 100644
--- a/src/phone.cpp
+++ b/src/phone.cpp
@@ -3054,7 +3054,7 @@ bool t_phone::add_phone_user(const t_user &user_config, t_user **dup_user) {
// Check if there is already another profile having
// the same contact name.
if (user->get_contact_name() == user_config.get_contact_name() &&
- USER_HOST(user, AUTO_IP4_ADDRESS) == USER_HOST(&user_config, AUTO_IP4_ADDRESS) &&
+ phone->get_ip_sip_locked(user, AUTO_IP4_ADDRESS) == phone->get_ip_sip_locked(&user_config, AUTO_IP4_ADDRESS) &&
(*i)->is_active())
{
*dup_user = user;
@@ -3160,9 +3160,13 @@ t_presence_epa *t_phone::ref_presence_epa(t_user *user) {
}
string t_phone::get_ip_sip(const t_user *user, const string &auto_ip) const {
+ t_rwmutex_reader x(phone_users_mtx);
+ return get_ip_sip_locked(user, auto_ip);
+}
+
+string t_phone::get_ip_sip_locked(const t_user *user, const string &auto_ip) const {
string result;
- t_rwmutex_reader x(phone_users_mtx);
t_phone_user *pu = find_phone_user(user->get_profile_name());
if (pu) {
result = pu->get_ip_sip(auto_ip);
diff --git a/src/phone.h b/src/phone.h
index f9c18d8..76d2a49 100644
--- a/src/phone.h
+++ b/src/phone.h
@@ -256,6 +256,8 @@ protected:
*/
t_line *find_line_in_dialog_request(t_request *r, t_tid tid);
+ // Variation of get_ip_sip() for when phone_users_mtx is already locked
+ string get_ip_sip_locked(const t_user *user, const string &auto_ip) const;
// Events
void recvd_provisional(t_response *r, t_tuid tuid, t_tid tid);
void recvd_success(t_response *r, t_tuid tuid, t_tid tid);