<p>N A has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/18824">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">res_pjsip_logger: Add method-based logging option.<br><br>Expands the pjsip logger to support the ability to filter<br>by SIP message type (INVITE, CANCEL, ACK, BYE, REGISTER,<br>and OPTION). This can make certain types of SIP debugging<br>easier by only logging messages of particular method(s).<br><br>ASTERISK-30146 #close<br><br>Change-Id: Idd03bd9b466b40e4bca7769437d52ac13a957cf9<br>---<br>A doc/CHANGES-staging/res_pjsip_logger_method.txt<br>M res/res_pjsip_logger.c<br>2 files changed, 105 insertions(+), 6 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/24/18824/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/doc/CHANGES-staging/res_pjsip_logger_method.txt b/doc/CHANGES-staging/res_pjsip_logger_method.txt</span><br><span>new file mode 100644</span><br><span>index 0000000..4add8a3</span><br><span>--- /dev/null</span><br><span>+++ b/doc/CHANGES-staging/res_pjsip_logger_method.txt</span><br><span>@@ -0,0 +1,5 @@</span><br><span style="color: hsl(120, 100%, 40%);">+Subject: res_pjsip_logger</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+SIP messages can now be filtered by SIP method,</span><br><span style="color: hsl(120, 100%, 40%);">+allowing for more granular debugging to be done</span><br><span style="color: hsl(120, 100%, 40%);">+in the CLI.</span><br><span>diff --git a/res/res_pjsip_logger.c b/res/res_pjsip_logger.c</span><br><span>index 957020f..9f17dc8 100644</span><br><span>--- a/res/res_pjsip_logger.c</span><br><span>+++ b/res/res_pjsip_logger.c</span><br><span>@@ -99,6 +99,22 @@</span><br><span> uint16_t checksum; /*! \brief Packet checksum, left uncalculated for our purposes */</span><br><span> };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! \brief PJSIP Method Logging */</span><br><span style="color: hsl(120, 100%, 40%);">+struct pjsip_method_logger {</span><br><span style="color: hsl(120, 100%, 40%);">+ /*! \brief Whether to log INVITEs */</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int log_method_invite:1;</span><br><span style="color: hsl(120, 100%, 40%);">+ /*! \brief Whether to log CANCELs */</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int log_method_cancel:1;</span><br><span style="color: hsl(120, 100%, 40%);">+ /*! \brief Whether to log ACKs */</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int log_method_ack:1;</span><br><span style="color: hsl(120, 100%, 40%);">+ /*! \brief Whether to log BYEs */</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int log_method_bye:1;</span><br><span style="color: hsl(120, 100%, 40%);">+ /*! \brief Whether to log REGISTERs */</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int log_method_register:1;</span><br><span style="color: hsl(120, 100%, 40%);">+ /*! \brief Whether to log OPTIONs */</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned int log_method_option:1;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! \brief PJSIP Logging Session */</span><br><span> struct pjsip_logger_session {</span><br><span> /*! \brief Explicit addresses or ranges being logged */</span><br><span>@@ -115,6 +131,8 @@</span><br><span> unsigned int log_to_verbose:1;</span><br><span> /*! \brief Whether to log to pcap or not */</span><br><span> unsigned int log_to_pcap:1;</span><br><span style="color: hsl(120, 100%, 40%);">+ /*! \brief Whether to log specific SIP methods */</span><br><span style="color: hsl(120, 100%, 40%);">+ struct pjsip_method_logger log_methods;</span><br><span> };</span><br><span> </span><br><span> /*! \brief The default logger session */</span><br><span>@@ -149,7 +167,7 @@</span><br><span> }</span><br><span> </span><br><span> /*! \brief See if we pass debug IP filter */</span><br><span style="color: hsl(0, 100%, 40%);">-static inline int pjsip_log_test_addr(const struct pjsip_logger_session *session, const char *address, int port)</span><br><span style="color: hsl(120, 100%, 40%);">+static inline int pjsip_log_test_addr(const struct pjsip_logger_session *session, const char *address, int port, const pjsip_method *method)</span><br><span> {</span><br><span> struct ast_sockaddr test_addr;</span><br><span> </span><br><span>@@ -161,6 +179,26 @@</span><br><span> return 1;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* If logging specific SIP methods, do so. */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (session->log_methods.log_method_invite && !pjsip_method_cmp(method, &pjsip_invite_method)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ if (session->log_methods.log_method_cancel && !pjsip_method_cmp(method, &pjsip_cancel_method)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ if (session->log_methods.log_method_ack && !pjsip_method_cmp(method, &pjsip_ack_method)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ if (session->log_methods.log_method_bye && !pjsip_method_cmp(method, &pjsip_bye_method)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ if (session->log_methods.log_method_register && !pjsip_method_cmp(method, &pjsip_register_method)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ if (session->log_methods.log_method_option && !pjsip_method_cmp(method, &pjsip_options_method)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /* A null address was passed in or no explicit matches. Just reject it. */</span><br><span> if (ast_strlen_zero(address) || !session->matches) {</span><br><span> return 0;</span><br><span>@@ -270,7 +308,7 @@</span><br><span> char buffer[AST_SOCKADDR_BUFLEN];</span><br><span> </span><br><span> ao2_rdlock(default_logger);</span><br><span style="color: hsl(0, 100%, 40%);">- if (!pjsip_log_test_addr(default_logger, tdata->tp_info.dst_name, tdata->tp_info.dst_port)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!pjsip_log_test_addr(default_logger, tdata->tp_info.dst_name, tdata->tp_info.dst_port, &tdata->msg->line.req.method)) {</span><br><span> ao2_unlock(default_logger);</span><br><span> return PJ_SUCCESS;</span><br><span> }</span><br><span>@@ -302,7 +340,7 @@</span><br><span> }</span><br><span> </span><br><span> ao2_rdlock(default_logger);</span><br><span style="color: hsl(0, 100%, 40%);">- if (!pjsip_log_test_addr(default_logger, rdata->pkt_info.src_name, rdata->pkt_info.src_port)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!pjsip_log_test_addr(default_logger, rdata->pkt_info.src_name, rdata->pkt_info.src_port, &rdata->msg_info.msg->line.req.method)) {</span><br><span> ao2_unlock(default_logger);</span><br><span> return PJ_FALSE;</span><br><span> }</span><br><span>@@ -393,6 +431,59 @@</span><br><span> return CLI_SUCCESS;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static char *pjsip_enable_logger_method(int fd, const char *arg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ int added = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *methods = arg;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ao2_wrlock(default_logger);</span><br><span style="color: hsl(120, 100%, 40%);">+ default_logger->enabled = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Remove what already exists */</span><br><span style="color: hsl(120, 100%, 40%);">+ memset(&default_logger->log_methods, 0, sizeof(default_logger->log_methods));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (strcasestr(methods, "INVITE")) {</span><br><span style="color: hsl(120, 100%, 40%);">+ default_logger->log_methods.log_method_invite = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ added++;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ if (strcasestr(methods, "CANCEL")) {</span><br><span style="color: hsl(120, 100%, 40%);">+ default_logger->log_methods.log_method_cancel = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ added++;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ if (strcasestr(methods, "ACK")) {</span><br><span style="color: hsl(120, 100%, 40%);">+ default_logger->log_methods.log_method_ack = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ added++;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ if (strcasestr(methods, "BYE")) {</span><br><span style="color: hsl(120, 100%, 40%);">+ default_logger->log_methods.log_method_bye = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ added++;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ if (strcasestr(methods, "REGISTER")) {</span><br><span style="color: hsl(120, 100%, 40%);">+ default_logger->log_methods.log_method_register = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ added++;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ if (strcasestr(methods, "OPTION")) {</span><br><span style="color: hsl(120, 100%, 40%);">+ default_logger->log_methods.log_method_option = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ added++;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!added) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (fd >= 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_cli(fd, "Failed to add method '%s' for logging\n", methods);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ ao2_unlock(default_logger);</span><br><span style="color: hsl(120, 100%, 40%);">+ return CLI_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ao2_unlock(default_logger);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (fd >= 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_cli(fd, "PJSIP Logging Enabled for %d SIP Method%s\n", added, ESS(added));</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return CLI_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static char *pjsip_disable_logger(int fd)</span><br><span> {</span><br><span> ao2_wrlock(default_logger);</span><br><span>@@ -403,6 +494,7 @@</span><br><span> default_logger->pcap_filename[0] = '\0';</span><br><span> default_logger->log_to_verbose = 1;</span><br><span> default_logger->log_to_pcap = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ memset(&default_logger->log_methods, 0, sizeof(default_logger->log_methods));</span><br><span> </span><br><span> /* Stop logging to the PCAP file if active */</span><br><span> if (default_logger->pcap_file) {</span><br><span>@@ -472,13 +564,13 @@</span><br><span> const char *what;</span><br><span> </span><br><span> if (cmd == CLI_INIT) {</span><br><span style="color: hsl(0, 100%, 40%);">- e->command = "pjsip set logger {on|off|host|add|verbose|pcap}";</span><br><span style="color: hsl(120, 100%, 40%);">+ e->command = "pjsip set logger {on|off|host|add|method|verbose|pcap}";</span><br><span> e->usage =</span><br><span style="color: hsl(0, 100%, 40%);">- "Usage: pjsip set logger {on|off|host <name/subnet>|add <name/subnet>|verbose <on/off>|pcap <filename>}\n"</span><br><span style="color: hsl(120, 100%, 40%);">+ "Usage: pjsip set logger {on|off|host <name/subnet>|add <name/subnet>|method <method[|method2...]>|verbose <on/off>|pcap <filename>}\n"</span><br><span> " Enables or disabling logging of SIP packets\n"</span><br><span> " read on ports bound to PJSIP transports either\n"</span><br><span> " globally or enables logging for an individual\n"</span><br><span style="color: hsl(0, 100%, 40%);">- " host.\n";</span><br><span style="color: hsl(120, 100%, 40%);">+ " host or particular SIP method(s).\n";</span><br><span> return NULL;</span><br><span> } else if (cmd == CLI_GENERATE) {</span><br><span> return NULL;</span><br><span>@@ -497,6 +589,8 @@</span><br><span> return pjsip_enable_logger_host(a->fd, a->argv[e->args], 0);</span><br><span> } else if (!strcasecmp(what, "add")) {</span><br><span> return pjsip_enable_logger_host(a->fd, a->argv[e->args], 1);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (!strcasecmp(what, "method")) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return pjsip_enable_logger_method(a->fd, a->argv[e->args]);</span><br><span> } else if (!strcasecmp(what, "verbose")) {</span><br><span> return pjsip_set_logger_verbose(a->fd, a->argv[e->args]);</span><br><span> } else if (!strcasecmp(what, "pcap")) {</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/18824">change 18824</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/c/asterisk/+/18824"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: Idd03bd9b466b40e4bca7769437d52ac13a957cf9 </div>
<div style="display:none"> Gerrit-Change-Number: 18824 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: N A <mail@interlinked.x10host.com> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>