Index: channels/chan_sip.c =================================================================== --- channels/chan_sip.c (revision 193954) +++ channels/chan_sip.c (working copy) @@ -8083,12 +8083,15 @@ /*! \brief Remove registration data from realtime database or AST/DB when registration expires */ static void destroy_association(struct sip_peer *peer) { - if (!ast_test_flag(&global_flags[1], SIP_PAGE2_IGNOREREGEXPIRE)) { - if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT) && ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE)) { - ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "username", "", "regserver", "", NULL); - ast_update_realtime("sippeers", "name", peer->name, "lastms", "", NULL); - } else - ast_db_del("SIP/Registry", peer->name); + /* Do not check for ignoreregexpire here or we will loop constantly and + * take down the server. Instead, check prior to calling this function + * and avoid in-memory destruction of the peer. Realtime MUST remain + * consistent with in-memory structs. */ + if (ast_test_flag(&peer->flags[1], SIP_PAGE2_RT_FROMCONTACT) && ast_test_flag(&global_flags[1], SIP_PAGE2_RTUPDATE)) { + ast_update_realtime("sippeers", "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", "username", "", "regserver", "", NULL); + ast_update_realtime("sippeers", "name", peer->name, "lastms", "", NULL); + } else { + ast_db_del("SIP/Registry", peer->name); } }