]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-8042, FS-8182: add ping time (in ms) to sip_registrations table, displays as part...
authorMichael Jerris <mike@jerris.com>
Fri, 18 Sep 2015 21:55:10 +0000 (16:55 -0500)
committerMichael Jerris <mike@jerris.com>
Mon, 21 Sep 2015 22:46:35 +0000 (17:46 -0500)
src/mod/endpoints/mod_sofia/mod_sofia.c
src/mod/endpoints/mod_sofia/mod_sofia.h
src/mod/endpoints/mod_sofia/sofia.c
src/mod/endpoints/mod_sofia/sofia_glue.c
src/mod/endpoints/mod_sofia/sofia_reg.c

index 100e8527968c282b04bd94af6038f818a1c29a45..ab3b10992434c65673c4f40d1f0ccaa100c160e6 100644 (file)
@@ -2452,6 +2452,7 @@ static int show_reg_callback(void *pArg, int argc, char **argv, char **columnNam
                                                           "Agent:      \t%s\n"
                                                           "Status:     \t%s(%s) EXP(%s) EXPSECS(%d)\n"
                                                           "Ping-Status:\t%s\n"
+                                                          "Ping-Time:\t%0.2f\n"
                                                           "Host:       \t%s\n"
                                                           "IP:         \t%s\n"
                                                           "Port:       \t%s\n"
@@ -2460,7 +2461,8 @@ static int show_reg_callback(void *pArg, int argc, char **argv, char **columnNam
                                                           "MWI-Account:\t%s@%s\n\n",
                                                           switch_str_nil(argv[0]), switch_str_nil(argv[1]), switch_str_nil(argv[2]), switch_str_nil(argv[3]),
                                                           switch_str_nil(argv[7]), switch_str_nil(argv[4]), switch_str_nil(argv[5]), exp_buf, exp_secs, switch_str_nil(argv[18]),
-                                                          switch_str_nil(argv[11]), switch_str_nil(argv[12]), switch_str_nil(argv[13]), switch_str_nil(argv[14]),
+                                                          (float)atoll(switch_str_nil(argv[19]))/1000, switch_str_nil(argv[11]), switch_str_nil(argv[12]),
+                                                          switch_str_nil(argv[13]), switch_str_nil(argv[14]),
                                                           switch_str_nil(argv[15]), switch_str_nil(argv[16]), switch_str_nil(argv[17]));
        return 0;
 }
@@ -2494,6 +2496,7 @@ static int show_reg_callback_xml(void *pArg, int argc, char **argv, char **colum
        cb->stream->write_function(cb->stream, "        <status>%s(%s) exp(%s) expsecs(%d)</status>\n", switch_str_nil(argv[4]), switch_str_nil(argv[5]),
                                                           exp_buf, exp_secs);
        cb->stream->write_function(cb->stream, "        <ping-status>%s</ping-status>\n", switch_str_nil(argv[18]));
+       cb->stream->write_function(cb->stream, "        <ping-time>%0.2f</ping-time>\n", (float)atoll(switch_str_nil(argv[19]))/1000);
        cb->stream->write_function(cb->stream, "        <host>%s</host>\n", switch_str_nil(argv[11]));
        cb->stream->write_function(cb->stream, "        <network-ip>%s</network-ip>\n", switch_str_nil(argv[12]));
        cb->stream->write_function(cb->stream, "        <network-port>%s</network-port>\n", switch_str_nil(argv[13]));
@@ -2718,19 +2721,19 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t
                                if (!sql && argv[2] && !strcasecmp(argv[2], "pres") && argv[3]) {
                                        sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,"
                                                                                 "rpid,expires,user_agent,server_user,server_host,profile_name,hostname,"
-                                                                                "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status"
+                                                                                "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status,ping_time"
                                                                                 " from sip_registrations where profile_name='%q' and presence_hosts like '%%%q%%'", profile->name, argv[3]);
                                }
                                if (!sql && argv[2] && !strcasecmp(argv[2], "reg") && argv[3]) {
                                        sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,"
                                                                                 "rpid,expires,user_agent,server_user,server_host,profile_name,hostname,"
-                                                                                "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host, ping_status"
+                                                                                "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host, ping_status,ping_time"
                                                                                 " from sip_registrations where profile_name='%q' and contact like '%%%q%%'", profile->name, argv[3]);
                                }
                                if (!sql && argv[2] && !strcasecmp(argv[2], "reg")) {
                                        sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,"
                                                                                 "rpid,expires,user_agent,server_user,server_host,profile_name,hostname,"
-                                                                                "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status"
+                                                                                "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status,ping_time"
                                                                                 " from sip_registrations where profile_name='%q'", profile->name);
                                }
                                if (!sql && argv[2] && !strcasecmp(argv[2], "user") && argv[3]) {
@@ -2757,7 +2760,7 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t
 
                                        sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,"
                                                                                 "rpid,expires,user_agent,server_user,server_host,profile_name,hostname,"
-                                                                                "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status"
+                                                                                "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status,ping_time"
                                                                                 " from sip_registrations where profile_name='%q' and %s", profile->name, sqlextra);
                                        switch_safe_free(dup);
                                        switch_safe_free(sqlextra);
@@ -3022,21 +3025,21 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl
 
                                        sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,"
                                                                                 "rpid,expires,user_agent,server_user,server_host,profile_name,hostname,"
-                                                                                "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status"
+                                                                                "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status,ping_time"
                                                                                 " from sip_registrations where profile_name='%q' and presence_hosts like '%%%q%%'", profile->name, argv[3]);
                                }
                                if (!sql && argv[2] && !strcasecmp(argv[2], "reg") && argv[3]) {
 
                                        sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,"
                                                                                 "rpid,expires,user_agent,server_user,server_host,profile_name,hostname,"
-                                                                                "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status"
+                                                                                "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status,ping_time"
                                                                                 " from sip_registrations where profile_name='%q' and contact like '%%%q%%'", profile->name, argv[3]);
                                }
                                if (!sql && argv[2] && !strcasecmp(argv[2], "reg")) {
 
                                        sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,"
                                                                                 "rpid,expires,user_agent,server_user,server_host,profile_name,hostname,"
-                                                                                "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status"
+                                                                                "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status,ping_time"
                                                                                 " from sip_registrations where profile_name='%q'", profile->name);
                                }
                                if (!sql && argv[2] && !strcasecmp(argv[2], "user") && argv[3]) {
@@ -3063,7 +3066,7 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl
 
                                        sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,"
                                                                                 "rpid,expires,user_agent,server_user,server_host,profile_name,hostname,"
-                                                                                "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status"
+                                                                                "network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host,ping_status,ping_time"
                                                                                 " from sip_registrations where profile_name='%q' and %s", profile->name, sqlextra);
                                        switch_safe_free(dup);
                                        switch_safe_free(sqlextra);
index f594828db3b562785753373c76fd6924ca6c1898..8aa89eb4738c50a4b7ac29e870b5e3fd0d3382c2 100644 (file)
@@ -175,6 +175,7 @@ struct sofia_private {
        int destroy_me;
        int is_call;
        int is_static;
+       switch_time_t ping_sent;
 };
 
 #define set_param(ptr,val) if (ptr) {free(ptr) ; ptr = NULL;} if (val) {ptr = strdup(val);}
index 7a7331a94a2b581cc6598a2fcf8a41ca65267a1b..e535b1a366da832485828475ac6e39ed0d6a8093 100644 (file)
@@ -5742,6 +5742,11 @@ static void sofia_handle_sip_r_options(switch_core_session_t *session, int statu
                int sip_user_ping_max = profile->sip_user_ping_max;
 
                char *sip_user = switch_mprintf("%s@%s", sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host);
+               int ping_time = 0;
+
+               if (sofia_private && sofia_private->ping_sent) {
+                       ping_time = switch_time_now() - sofia_private->ping_sent;
+               }
 
                sip_user_status.status = ping_status;
                sip_user_status.status_len = sizeof(ping_status);
@@ -5757,8 +5762,8 @@ static void sofia_handle_sip_r_options(switch_core_session_t *session, int statu
                        if (sip_user_status.count >= 0) {
                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Ping to sip user '%s@%s' failed with code %d - count %d, state %s\n",
                                                  sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, status, sip_user_status.count, sip_user_status.status);
-                               sql = switch_mprintf("update sip_registrations set ping_count=%d where sip_user='%s' and sip_host='%s' and call_id='%q'", sip_user_status.count,
-                                                    sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
+                               sql = switch_mprintf("update sip_registrations set ping_count=%d, ping_time=%d where sip_user='%s' and sip_host='%s' and call_id='%q'",
+                                                                        sip_user_status.count, ping_time, sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
                                sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
                                switch_safe_free(sql);
                        }
@@ -5766,8 +5771,8 @@ static void sofia_handle_sip_r_options(switch_core_session_t *session, int statu
                                if (strcmp(sip_user_status.status, "Unreachable")) {
                                        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Sip user '%s@%s' is now Unreachable\n",
                                                          sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host);
-                                       sql = switch_mprintf("update sip_registrations set ping_status='Unreachable' where sip_user='%s' and sip_host='%s' and call_id='%q'",
-                                                            sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
+                                       sql = switch_mprintf("update sip_registrations set ping_status='Unreachable', ping_time=%d where sip_user='%s' and sip_host='%s' and call_id='%q'",
+                                                                                ping_time, sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
                                        sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
                                        switch_safe_free(sql);
                                        sofia_reg_fire_custom_sip_user_state_event(profile, sip_user, sip_user_status.contact, sip->sip_to->a_url->url_user,
@@ -5778,8 +5783,8 @@ static void sofia_handle_sip_r_options(switch_core_session_t *session, int statu
                                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Expire sip user '%s@%s' due to options failure\n",
                                                                  sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host);
 
-                                               sql = switch_mprintf("update sip_registrations set expires=%ld where sip_user='%s' and sip_host='%s' and call_id='%q'",
-                                                                    (long) now, sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
+                                               sql = switch_mprintf("update sip_registrations set expires=%ld, ping_time=%d where sip_user='%s' and sip_host='%s' and call_id='%q'",
+                                                                                        (long) now, ping_time, sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
                                                sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
                                                switch_safe_free(sql);
                                        }
@@ -5790,8 +5795,8 @@ static void sofia_handle_sip_r_options(switch_core_session_t *session, int statu
                        if (sip_user_status.count <= sip_user_ping_max) {
                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Ping to sip user '%s@%s' succeeded with code %d - count %d, state %s\n",
                                                  sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, status, sip_user_status.count, sip_user_status.status);
-                               sql = switch_mprintf("update sip_registrations set ping_count=%d where sip_user='%s' and sip_host='%s' and call_id='%q'", sip_user_status.count,
-                                                    sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
+                               sql = switch_mprintf("update sip_registrations set ping_count=%d, ping_time=%d where sip_user='%s' and sip_host='%s' and call_id='%q'",
+                                                                        sip_user_status.count, ping_time, sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host, call_id);
                                sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
                                switch_safe_free(sql);
                        }
index c6c1c8d80e6a457e5bd3d198fe0247cd110b790b..8e99457f881db6c150bfe43c9381caf2c1261ecb 100644 (file)
@@ -2008,6 +2008,8 @@ int sofia_glue_init_sql(sofia_profile_t *profile)
                "   status           VARCHAR(255),\n"
                "   ping_status      VARCHAR(255),\n"
                "   ping_count       INTEGER,\n"
+               "   ping_time        BIGINT,\n"
+               "   force_ping       INTEGER,\n"
                "   rpid             VARCHAR(255),\n"
                "   expires          BIGINT,\n"
                "   ping_expires     INTEGER not null default 0,\n"
@@ -2225,6 +2227,8 @@ int sofia_glue_init_sql(sofia_profile_t *profile)
        switch_cache_db_test_reactive(dbh, "select ping_count from sip_registrations", NULL, "alter table sip_registrations add column ping_count INTEGER default 0");
        switch_cache_db_test_reactive(dbh, "select ping_status from sip_registrations", NULL, "alter table sip_registrations add column ping_status VARCHAR(255) default 'Reachable'");
        switch_cache_db_test_reactive(dbh, "select ping_expires from sip_registrations", NULL, "alter table sip_registrations add column ping_expires INTEGER not null default 0");
+       switch_cache_db_test_reactive(dbh, "select ping_time from sip_registrations", NULL, "alter table sip_registrations add column ping_time BIGINT not null default 0");
+       switch_cache_db_test_reactive(dbh, "select force_ping from sip_registrations", NULL, "alter table sip_registrations add column force_ping INTEGER not null default 0");
        
        test2 = switch_mprintf("%s;%s", test_sql, test_sql);
                        
index 8c3e4b6fabee9816319db4326325063c65702518..42f7cdc19a3cf35c976c720d76cc20bc5687aa7a 100644 (file)
@@ -599,6 +599,7 @@ int sofia_reg_nat_callback(void *pArg, int argc, char **argv, char **columnNames
        char to[512] = "", call_id[512] = "";
        sofia_destination_t *dst = NULL;
        switch_uuid_t uuid;
+       sofia_private_t *pvt;
 
        switch_snprintf(to, sizeof(to), "sip:%s@%s", argv[1], argv[2]);
 
@@ -613,7 +614,15 @@ int sofia_reg_nat_callback(void *pArg, int argc, char **argv, char **columnNames
        
        nh = nua_handle(profile->nua, NULL, SIPTAG_FROM_STR(profile->url), SIPTAG_TO_STR(to), NUTAG_URL(dst->contact), SIPTAG_CONTACT_STR(profile->url),
                                        SIPTAG_CALL_ID_STR(call_id), TAG_END());
-       nua_handle_bind(nh, &mod_sofia_globals.destroy_private);
+
+       pvt = malloc(sizeof(*pvt));
+       switch_assert(pvt);
+       memset(pvt, 0, sizeof(*pvt));
+       pvt->destroy_nh = 1;
+       pvt->destroy_me = 1;
+       pvt->ping_sent = switch_time_now();
+       nua_handle_bind(nh, pvt);
+
        nua_options(nh, 
                                NTATAG_SIP_T2(5000),
                                NTATAG_SIP_T4(10000),
@@ -869,64 +878,70 @@ void sofia_reg_check_ping_expire(sofia_profile_t *profile, time_t now, int inter
        char *sql;
        int mean = interval / 2;
        long next, irand;
+       char buf[32] = "";
+       int count;
 
        if (now) {
                if (sofia_test_pflag(profile, PFLAG_ALL_REG_OPTIONS_PING)) {
                        sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,rpid,"
-                                                       "expires,user_agent,server_user,server_host,profile_name"
- " from sip_registrations where hostname='%s' and " 
- "profile_name='%s' and orig_hostname='%s' and "
- "ping_expires > 0 and ping_expires <= %ld", mod_sofia_globals.hostname, profile->name, mod_sofia_globals.hostname, (long) now); 
+                                                                "expires,user_agent,server_user,server_host,profile_name "
+                                                                "from sip_registrations where hostname='%s' and "
+                                                                "profile_name='%s' and orig_hostname='%s' and "
+                                                                "ping_expires > 0 and ping_expires <= %ld",
+                                                                mod_sofia_globals.hostname, profile->name, mod_sofia_globals.hostname, (long) now);
                        
                        sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_reg_nat_callback, profile);
                        switch_safe_free(sql);
                } else if (sofia_test_pflag(profile, PFLAG_UDP_NAT_OPTIONS_PING)) {
-                       sql = switch_mprintf(   " select call_id,sip_user,sip_host,contact,status,rpid, "
-                                               " expires,user_agent,server_user,server_host,profile_name "
-                                               " from sip_registrations where status like '%%UDP-NAT%%' "
-                                               " and hostname='%s' and profile_name='%s' and ping_expires > 0 and ping_expires <= %ld ",
-                                               mod_sofia_globals.hostname, profile->name, (long) now); 
+                       sql = switch_mprintf(" select call_id,sip_user,sip_host,contact,status,rpid, "
+                                                                " expires,user_agent,server_user,server_host,profile_name "
+                                                                " from sip_registrations where (status like '%%UDP-NAT%%' or force_ping=1)"
+                                                                " and hostname='%s' and profile_name='%s' and ping_expires > 0 and ping_expires <= %ld ",
+                                                                mod_sofia_globals.hostname, profile->name, (long) now);
                        
                        sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_reg_nat_callback, profile);
                        switch_safe_free(sql);
                } else if (sofia_test_pflag(profile, PFLAG_NAT_OPTIONS_PING)) {
                        sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,rpid,"
-                                                       "expires,user_agent,server_user,server_host,profile_name"
-                                                       " from sip_registrations where (status like '%%NAT%%' "
- "or contact like '%%fs_nat=yes%%') and hostname='%s' " 
- "and profile_name='%s' and orig_hostname='%s' and "
- "ping_expires > 0 and ping_expires <= %ld", mod_sofia_globals.hostname, profile->name, mod_sofia_globals.hostname, (long) now); 
+                                                                "expires,user_agent,server_user,server_host,profile_name "
+                                                                "from sip_registrations where (status like '%%NAT%%' "
+                                                                "or contact like '%%fs_nat=yes%%' or force_ping=1) and hostname='%s' "
+                                                                "and profile_name='%s' and orig_hostname='%s' and "
+                                                                "ping_expires > 0 and ping_expires <= %ld",
+                                                                mod_sofia_globals.hostname, profile->name, mod_sofia_globals.hostname, (long) now);
                        
+                       sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_reg_nat_callback, profile);
+                       switch_safe_free(sql);
+               } else {
+                       sql = switch_mprintf("select call_id,sip_user,sip_host,contact,status,rpid,"
+                                                                "expires,user_agent,server_user,server_host,profile_name "
+                                                                "from sip_registrations where force_ping=1 and hostname='%s' "
+                                                                "and profile_name='%s' and orig_hostname='%s' and "
+                                                                "ping_expires > 0 and ping_expires <= %ld",
+                                                                mod_sofia_globals.hostname, profile->name, mod_sofia_globals.hostname, (long) now);
+
                        sofia_glue_execute_sql_callback(profile, profile->dbh_mutex, sql, sofia_reg_nat_callback, profile);
                        switch_safe_free(sql);
                }
 
-               if (sofia_test_pflag(profile, PFLAG_ALL_REG_OPTIONS_PING) ||
-                       sofia_test_pflag(profile, PFLAG_UDP_NAT_OPTIONS_PING) || 
-                       sofia_test_pflag(profile, PFLAG_NAT_OPTIONS_PING)) {
-                       char buf[32] = "";
-                       int count;
+               sql = switch_mprintf("select count(*) from sip_registrations where hostname='%q' and profile_name='%q' and ping_expires <= %ld",
+                                                        mod_sofia_globals.hostname, profile->name, (long) now);
 
-                       sql = switch_mprintf("select count(*) from sip_registrations where hostname='%q' and profile_name='%q' and ping_expires <= %ld",
-                                               mod_sofia_globals.hostname, profile->name, (long) now);
+               sofia_glue_execute_sql2str(profile, profile->dbh_mutex, sql, buf, sizeof(buf));
+               switch_safe_free(sql);
+               count = atoi(buf);
 
-                       sofia_glue_execute_sql2str(profile, profile->dbh_mutex, sql, buf, sizeof(buf));
-                       switch_safe_free(sql);
-                       count = atoi(buf);
+               /* only update if needed */
+               if (count) {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "Updating ping expires for profile %s\n", profile->name);
+                       irand = mean + sofia_reg_uniform_distribution(interval);
+                       next = (long) now + irand;
 
-                       /* only update if needed */
-                       if (count) {
-                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG9, "Updating ping expires for profile %s\n", profile->name);
-                               irand = mean + sofia_reg_uniform_distribution(interval);
-                               next = (long) now + irand;
-       
-                               sql = switch_mprintf("update sip_registrations set ping_expires = %ld where hostname='%q' and profile_name='%q' and ping_expires <= %ld ",
-                                                       next, mod_sofia_globals.hostname, profile->name, (long) now);
-                               sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
-                       }
+                       sql = switch_mprintf("update sip_registrations set ping_expires = %ld where hostname='%q' and profile_name='%q' and ping_expires <= %ld ",
+                                                                next, mod_sofia_globals.hostname, profile->name, (long) now);
+                       sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE);
                }
        }
-
 }
 
 
@@ -1252,6 +1267,7 @@ uint8_t sofia_reg_handle_register_token(nua_t *nua, sofia_profile_t *profile, nu
        const char *agent = "unknown";
        const char *pres_on_reg = NULL;
        int send_pres = 0;
+       int force_ping = 0;
        int is_tls = 0, is_tcp = 0, is_ws = 0, is_wss = 0;
        char expbuf[35] = "";
        time_t reg_time = switch_epoch_time_now(NULL);
@@ -1774,6 +1790,15 @@ uint8_t sofia_reg_handle_register_token(nua_t *nua, sofia_profile_t *profile, nu
                mwi_host = (char *) reg_host;
        }
 
+       /* per-account enable options ping on register */
+       if (v_event && *v_event && (var = switch_event_get_header(*v_event, "force_ping"))) {
+               if (switch_true(var)) {
+                       force_ping = 1;
+               } else {
+                       force_ping = 0;
+               }
+       }
+
        if (regtype != REG_REGISTER) {
                switch_goto_int(r, 0, end);
        }
@@ -1880,22 +1905,22 @@ uint8_t sofia_reg_handle_register_token(nua_t *nua, sofia_profile_t *profile, nu
                        sql = switch_mprintf("insert into sip_registrations "
                                        "(call_id,sip_user,sip_host,presence_hosts,contact,status,rpid,expires,"
                                        "user_agent,server_user,server_host,profile_name,hostname,network_ip,network_port,sip_username,sip_realm,"
-                                       "mwi_user,mwi_host, orig_server_host, orig_hostname, sub_host, ping_status, ping_count) "
-                                       "values ('%q','%q', '%q','%q','%q','%q', '%q', %ld, '%q', '%q', '%q', '%q', '%q', '%q', '%q','%q','%q','%q','%q','%q','%q','%q', '%q', %d)", 
+                                       "mwi_user,mwi_host, orig_server_host, orig_hostname, sub_host, ping_status, ping_count, force_ping) "
+                                       "values ('%q','%q', '%q','%q','%q','%q', '%q', %ld, '%q', '%q', '%q', '%q', '%q', '%q', '%q','%q','%q','%q','%q','%q','%q','%q', '%q', %d, %d)",
                                        call_id, to_user, reg_host, profile->presence_hosts ? profile->presence_hosts : "", 
                                        contact_str, reg_desc, rpid, (long) reg_time + (long) exptime + profile->sip_expires_late_margin,
                                        agent, from_user, guess_ip4, profile->name, mod_sofia_globals.hostname, network_ip, network_port_c, username, realm, 
-                                                                mwi_user, mwi_host, guess_ip4, mod_sofia_globals.hostname, sub_host, "Reachable", 0);
+                                                                mwi_user, mwi_host, guess_ip4, mod_sofia_globals.hostname, sub_host, "Reachable", 0, force_ping);
                } else {
                        sql = switch_mprintf("update sip_registrations set call_id='%q',"
                                                                 "sub_host='%q', network_ip='%q',network_port='%q',"
                                                                 "presence_hosts='%q', server_host='%q', orig_server_host='%q',"
                                                                 "hostname='%q', orig_hostname='%q',"
-                                                                "expires = %ld where sip_user='%q' and sip_username='%q' and sip_host='%q' and contact='%q'", 
+                                                                "expires = %ld, force_ping=%d where sip_user='%q' and sip_username='%q' and sip_host='%q' and contact='%q'",
                                                                 call_id, sub_host, network_ip, network_port_c,
                                                                 profile->presence_hosts ? profile->presence_hosts : "", guess_ip4, guess_ip4,
                                                                  mod_sofia_globals.hostname, mod_sofia_globals.hostname,
-                                                                (long) reg_time + (long) exptime + profile->sip_expires_late_margin,
+                                                                (long) reg_time + (long) exptime + profile->sip_expires_late_margin, force_ping,
                                                                 to_user, username, reg_host, contact_str);
                }