<p>Joshua Colp <strong>submitted</strong> this change.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/13312">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Joshua Colp: Looks good to me, but someone else must approve; Approved for Submit
  Benjamin Keith Ford: Looks good to me, but someone else must approve
  George Joseph: Looks good to me, approved

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">res_pjsip_endpoint_identifier_ip.c: Add port matching support<br><br>Adds source port matching support when IP matching is used:<br><br>  [example]<br>  type = identify<br>  match = 1.2.3.4:5060/32, 1.2.3.4:6000/32, asterisk.org:4444<br><br>If the IP matches but the source port does not, we reject and search for<br>alternatives. SRV lookups are still performed if enabled (srv_lookups = yes),<br>unless the configured FQDN includes a port number in which case just a host<br>lookup is performed.<br><br>ASTERISK-28639 #close<br>Reported by: Mitch Claborn<br><br>Change-Id: I256d5bd5d478b95f526e2f80ace31b690eebba92<br>---<br>M configs/samples/pjsip.conf.sample<br>A doc/CHANGES-staging/res_pjsip_endpoint_identifier_ip_match_port.txt<br>M include/asterisk/acl.h<br>M main/acl.c<br>M res/res_pjsip_endpoint_identifier_ip.c<br>5 files changed, 120 insertions(+), 24 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/configs/samples/pjsip.conf.sample b/configs/samples/pjsip.conf.sample</span><br><span>index 9e6365e..fd2d742 100644</span><br><span>--- a/configs/samples/pjsip.conf.sample</span><br><span>+++ b/configs/samples/pjsip.conf.sample</span><br><span>@@ -251,6 +251,7 @@</span><br><span> ;endpoint=mytrunk</span><br><span> ;match=198.51.100.1</span><br><span> ;match=198.51.100.2</span><br><span style="color: hsl(120, 100%, 40%);">+;match=192.168.10.0:5061/24</span><br><span> </span><br><span> </span><br><span> ;=============ENDPOINT CONFIGURED AS A TRUNK, INBOUND AUTH AND REGISTRATION===</span><br><span>diff --git a/doc/CHANGES-staging/res_pjsip_endpoint_identifier_ip_match_port.txt b/doc/CHANGES-staging/res_pjsip_endpoint_identifier_ip_match_port.txt</span><br><span>new file mode 100644</span><br><span>index 0000000..3881d64</span><br><span>--- /dev/null</span><br><span>+++ b/doc/CHANGES-staging/res_pjsip_endpoint_identifier_ip_match_port.txt</span><br><span>@@ -0,0 +1,8 @@</span><br><span style="color: hsl(120, 100%, 40%);">+Subject: res_pjsip_endpoint_identifier_ip</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+In 'type = identify' sections, the addresses specified for the 'match'</span><br><span style="color: hsl(120, 100%, 40%);">+clause can now include a port number. For IP addresses, the port is</span><br><span style="color: hsl(120, 100%, 40%);">+provided by including a colon after the address, followed by the</span><br><span style="color: hsl(120, 100%, 40%);">+desired port number. If supplied, the netmask should follow the port</span><br><span style="color: hsl(120, 100%, 40%);">+number. To specify a port for IPv6 addresses, the address itself must</span><br><span style="color: hsl(120, 100%, 40%);">+be enclosed in brackets to be parsed correctly.</span><br><span>diff --git a/include/asterisk/acl.h b/include/asterisk/acl.h</span><br><span>index b8a4f72..fe49a5b 100644</span><br><span>--- a/include/asterisk/acl.h</span><br><span>+++ b/include/asterisk/acl.h</span><br><span>@@ -135,6 +135,29 @@</span><br><span> struct ast_ha *ast_append_ha(const char *sense, const char *stuff, struct ast_ha *path, int *error);</span><br><span> </span><br><span> /*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief Add a new rule with optional port to a list of HAs</span><br><span style="color: hsl(120, 100%, 40%);">+ * \since 13.31.0, 16.8.0, 17.2.0</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \details</span><br><span style="color: hsl(120, 100%, 40%);">+ * This adds the new host access rule to the end of the list</span><br><span style="color: hsl(120, 100%, 40%);">+ * whose head is specified by the path parameter. Rules are</span><br><span style="color: hsl(120, 100%, 40%);">+ * evaluated in a way such that if multiple rules apply to</span><br><span style="color: hsl(120, 100%, 40%);">+ * a single IP address/subnet mask, then the rule latest</span><br><span style="color: hsl(120, 100%, 40%);">+ * in the list will be used.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param sense Either "permit" or "deny" (Actually any 'p' word will result</span><br><span style="color: hsl(120, 100%, 40%);">+ * in permission, and any other word will result in denial)</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param stuff The IP address and subnet mask, separated with a '/'. The subnet</span><br><span style="color: hsl(120, 100%, 40%);">+ * mask can either be in dotted-decimal format or in CIDR notation (i.e. 0-32). A</span><br><span style="color: hsl(120, 100%, 40%);">+ * port can be provided by placing it after the IP address, separated with a ':'.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param path The head of the HA list to which we wish to append our new rule. If</span><br><span style="color: hsl(120, 100%, 40%);">+ * NULL is passed, then the new rule will become the head of the list</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[out] error The integer error points to will be set non-zero if an error occurs</span><br><span style="color: hsl(120, 100%, 40%);">+ * \return The head of the HA list</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+struct ast_ha *ast_append_ha_with_port(const char *sense, const char *stuff, struct ast_ha *path, int *error);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*!</span><br><span>  * \brief Convert HAs to a comma separated string value</span><br><span>  * \param ha the starting ha head</span><br><span>  * \param buf string buffer to convert data to</span><br><span>diff --git a/main/acl.c b/main/acl.c</span><br><span>index 5028587..9179753 100644</span><br><span>--- a/main/acl.c</span><br><span>+++ b/main/acl.c</span><br><span>@@ -574,7 +574,7 @@</span><br><span>             ha->sense);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-struct ast_ha *ast_append_ha(const char *sense, const char *stuff, struct ast_ha *path, int *error)</span><br><span style="color: hsl(120, 100%, 40%);">+static struct ast_ha *append_ha_core(const char *sense, const char *stuff, struct ast_ha *path, int *error, int port_flags)</span><br><span> {</span><br><span>         struct ast_ha *ha;</span><br><span>   struct ast_ha *prev = NULL;</span><br><span>@@ -591,6 +591,8 @@</span><br><span>    }</span><br><span> </span><br><span>        while ((tmp = strsep(&list, ","))) {</span><br><span style="color: hsl(120, 100%, 40%);">+            uint16_t save_port;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>                if (!(ha = ast_calloc(1, sizeof(*ha)))) {</span><br><span>                    if (error) {</span><br><span>                                 *error = 1;</span><br><span>@@ -612,7 +614,7 @@</span><br><span>                    ha->sense = allowing;</span><br><span>             }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-           if (!ast_sockaddr_parse(&ha->addr, address, PARSE_PORT_FORBID)) {</span><br><span style="color: hsl(120, 100%, 40%);">+              if (!ast_sockaddr_parse(&ha->addr, address, port_flags)) {</span><br><span>                    ast_log(LOG_WARNING, "Invalid IP address: %s\n", address);</span><br><span>                         ast_free_ha(ha);</span><br><span>                     if (error) {</span><br><span>@@ -621,6 +623,11 @@</span><br><span>                  return ret;</span><br><span>          }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+         /* Be pedantic and zero out the port if we don't want it */</span><br><span style="color: hsl(120, 100%, 40%);">+               if ((port_flags & PARSE_PORT_MASK) == PARSE_PORT_FORBID) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        ast_sockaddr_set_port(&ha->addr, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+           }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>          /* If someone specifies an IPv4-mapped IPv6 address,</span><br><span>                  * we just convert this to an IPv4 ACL</span><br><span>                */</span><br><span>@@ -669,6 +676,10 @@</span><br><span>                   return ret;</span><br><span>          }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+         /* ast_sockaddr_apply_netmask() does not preserve the port, so we need to save and</span><br><span style="color: hsl(120, 100%, 40%);">+             * restore it */</span><br><span style="color: hsl(120, 100%, 40%);">+              save_port = ast_sockaddr_port(&ha->addr);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>           if (ast_sockaddr_apply_netmask(&ha->addr, &ha->netmask, &ha->addr)) {</span><br><span>                   /* This shouldn't happen because ast_sockaddr_parse would</span><br><span>                         * have failed much earlier on an unsupported address scheme</span><br><span>@@ -683,6 +694,8 @@</span><br><span>                   return ret;</span><br><span>          }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+         ast_sockaddr_set_port(&ha->addr, save_port);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>                if (prev) {</span><br><span>                  prev->next = ha;</span><br><span>          } else {</span><br><span>@@ -698,12 +711,30 @@</span><br><span>     return ret;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+struct ast_ha *ast_append_ha(const char *sense, const char *stuff, struct ast_ha *path, int *error)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  return append_ha_core(sense, stuff, path, error, PARSE_PORT_FORBID);</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%);">+struct ast_ha *ast_append_ha_with_port(const char *sense, const char *stuff, struct ast_ha *path, int *error)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   return append_ha_core(sense, stuff, path, error, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> void ast_ha_join(const struct ast_ha *ha, struct ast_str **buf)</span><br><span> {</span><br><span>    for (; ha; ha = ha->next) {</span><br><span style="color: hsl(120, 100%, 40%);">+                const char *addr;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           if (ast_sockaddr_port(&ha->addr)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    addr = ast_sockaddr_stringify(&ha->addr);</span><br><span style="color: hsl(120, 100%, 40%);">+              } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                      addr = ast_sockaddr_stringify_addr(&ha->addr);</span><br><span style="color: hsl(120, 100%, 40%);">+         }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>          ast_str_append(buf, 0, "%s%s/",</span><br><span>                    ha->sense == AST_SENSE_ALLOW ? "!" : "",</span><br><span style="color: hsl(0, 100%, 40%);">-                 ast_sockaddr_stringify_addr(&ha->addr));</span><br><span style="color: hsl(120, 100%, 40%);">+                       addr);</span><br><span>               /* Separated to avoid duplicating stringified addresses. */</span><br><span>          ast_str_append(buf, 0, "%s", ast_sockaddr_stringify_addr(&ha->netmask));</span><br><span>            if (ha->next) {</span><br><span>@@ -785,6 +816,7 @@</span><br><span>             struct ast_sockaddr result;</span><br><span>          struct ast_sockaddr mapped_addr;</span><br><span>             const struct ast_sockaddr *addr_to_use;</span><br><span style="color: hsl(120, 100%, 40%);">+               uint16_t save_port;</span><br><span> #if 0    /* debugging code */</span><br><span>                 char iabuf[INET_ADDRSTRLEN];</span><br><span>                 char iabuf2[INET_ADDRSTRLEN];</span><br><span>@@ -820,13 +852,22 @@</span><br><span>                        }</span><br><span>            }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+         /* ast_sockaddr_apply_netmask() does not preserve the port, so we need to save and</span><br><span style="color: hsl(120, 100%, 40%);">+             * restore it */</span><br><span style="color: hsl(120, 100%, 40%);">+              save_port = ast_sockaddr_port(addr_to_use);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>                /* For each rule, if this address and the netmask = the net address</span><br><span>             apply the current rule */</span><br><span>                 if (ast_sockaddr_apply_netmask(addr_to_use, &current_ha->netmask, &result)) {</span><br><span>                     /* Unlikely to happen since we know the address to be IPv4 or IPv6 */</span><br><span>                        continue;</span><br><span>            }</span><br><span style="color: hsl(0, 100%, 40%);">-               if (!ast_sockaddr_cmp_addr(&result, &current_ha->addr)) {</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                ast_sockaddr_set_port(&result, save_port);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+              if (!ast_sockaddr_cmp_addr(&result, &current_ha->addr)</span><br><span style="color: hsl(120, 100%, 40%);">+                && (!ast_sockaddr_port(&current_ha->addr)</span><br><span style="color: hsl(120, 100%, 40%);">+                     || ast_sockaddr_port(&current_ha->addr) == ast_sockaddr_port(&result))) {</span><br><span>                       res = current_ha->sense;</span><br><span>          }</span><br><span>    }</span><br><span>diff --git a/res/res_pjsip_endpoint_identifier_ip.c b/res/res_pjsip_endpoint_identifier_ip.c</span><br><span>index ac4057b..f8d5c70 100644</span><br><span>--- a/res/res_pjsip_endpoint_identifier_ip.c</span><br><span>+++ b/res/res_pjsip_endpoint_identifier_ip.c</span><br><span>@@ -63,7 +63,9 @@</span><br><span>                                           hostnames.  IP addresses may have a subnet mask appended.  The</span><br><span>                                               subnet mask may be written in either CIDR or dotted-decimal</span><br><span>                                          notation.  Separate the IP address and subnet mask with a slash</span><br><span style="color: hsl(0, 100%, 40%);">-                                         ('/').</span><br><span style="color: hsl(120, 100%, 40%);">+                                                ('/'). A source port can also be specified by adding a colon (':')</span><br><span style="color: hsl(120, 100%, 40%);">+                                            after the address but before the subnet mask, e.g.</span><br><span style="color: hsl(120, 100%, 40%);">+                                            3.2.1.0:5061/24.</span><br><span>                                             </para></span><br><span>                                        </description></span><br><span>                                 </configOption></span><br><span>@@ -310,7 +312,7 @@</span><br><span>  int num_addrs = 0, error = 0, i;</span><br><span>     int results = 0;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-    num_addrs = ast_sockaddr_resolve(&addrs, host, PARSE_PORT_FORBID, AST_AF_UNSPEC);</span><br><span style="color: hsl(120, 100%, 40%);">+ num_addrs = ast_sockaddr_resolve(&addrs, host, 0, AST_AF_UNSPEC);</span><br><span>        if (!num_addrs) {</span><br><span>            return -1;</span><br><span>   }</span><br><span>@@ -322,7 +324,7 @@</span><br><span>              }</span><br><span> </span><br><span>                /* We deny what we actually want to match because there is an implicit permit all rule for ACLs */</span><br><span style="color: hsl(0, 100%, 40%);">-              identify->matches = ast_append_ha("d", ast_sockaddr_stringify_addr(&addrs[i]), identify->matches, &error);</span><br><span style="color: hsl(120, 100%, 40%);">+            identify->matches = ast_append_ha_with_port("d", ast_sockaddr_stringify(&addrs[i]), identify->matches, &error);</span><br><span> </span><br><span>          if (!identify->matches || error) {</span><br><span>                        results = -1;</span><br><span>@@ -380,15 +382,20 @@</span><br><span>        }</span><br><span> </span><br><span>        while ((current_string = ast_strip(strsep(&input_string, ",")))) {</span><br><span style="color: hsl(0, 100%, 40%);">-                char *mask = strrchr(current_string, '/');</span><br><span style="color: hsl(120, 100%, 40%);">+            char *mask;</span><br><span style="color: hsl(120, 100%, 40%);">+           struct ast_sockaddr address;</span><br><span>                 int error = 0;</span><br><span> </span><br><span>           if (ast_strlen_zero(current_string)) {</span><br><span>                       continue;</span><br><span>            }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-           if (mask) {</span><br><span style="color: hsl(0, 100%, 40%);">-                     identify->matches = ast_append_ha("d", current_string, identify->matches, &error);</span><br><span style="color: hsl(120, 100%, 40%);">+                mask = strrchr(current_string, '/');</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                /* If it looks like a netmask is present, or we can immediately parse as an IP,</span><br><span style="color: hsl(120, 100%, 40%);">+                * hand things off to the ACL */</span><br><span style="color: hsl(120, 100%, 40%);">+              if (mask || ast_sockaddr_parse(&address, current_string, 0)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    identify->matches = ast_append_ha_with_port("d", current_string, identify->matches, &error);</span><br><span> </span><br><span>                         if (!identify->matches || error) {</span><br><span>                                ast_log(LOG_ERROR, "Failed to add address '%s' to ip endpoint identifier '%s'\n",</span><br><span>@@ -498,20 +505,23 @@</span><br><span>  /* Resolve the match addresses now */</span><br><span>        i = ao2_iterator_init(identify->hosts, 0);</span><br><span>        while ((current_string = ao2_iterator_next(&i))) {</span><br><span style="color: hsl(0, 100%, 40%);">-          struct ast_sockaddr address;</span><br><span>                 int results = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+              char *colon = strrchr(current_string, ':');</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-         /* If the provided string is not an IP address perform SRV resolution on it */</span><br><span style="color: hsl(0, 100%, 40%);">-          if (identify->srv_lookups && !ast_sockaddr_parse(&address, current_string, 0)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                 results = ip_identify_match_srv_lookup(identify, "_sip._udp", current_string,</span><br><span style="color: hsl(0, 100%, 40%);">-                         results);</span><br><span style="color: hsl(0, 100%, 40%);">-                       if (results != -1) {</span><br><span style="color: hsl(0, 100%, 40%);">-                            results = ip_identify_match_srv_lookup(identify, "_sip._tcp",</span><br><span style="color: hsl(0, 100%, 40%);">-                                 current_string, results);</span><br><span style="color: hsl(0, 100%, 40%);">-                       }</span><br><span style="color: hsl(0, 100%, 40%);">-                       if (results != -1) {</span><br><span style="color: hsl(0, 100%, 40%);">-                            results = ip_identify_match_srv_lookup(identify, "_sips._tcp",</span><br><span style="color: hsl(0, 100%, 40%);">-                                        current_string, results);</span><br><span style="color: hsl(120, 100%, 40%);">+             /* We skip SRV lookup if a colon is present, assuming a port was specified */</span><br><span style="color: hsl(120, 100%, 40%);">+         if (!colon) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 /* No port, and we know this is not an IP address, so perform SRV resolution on it */</span><br><span style="color: hsl(120, 100%, 40%);">+                 if (identify->srv_lookups) {</span><br><span style="color: hsl(120, 100%, 40%);">+                               results = ip_identify_match_srv_lookup(identify, "_sip._udp", current_string,</span><br><span style="color: hsl(120, 100%, 40%);">+                                       results);</span><br><span style="color: hsl(120, 100%, 40%);">+                             if (results != -1) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                  results = ip_identify_match_srv_lookup(identify, "_sip._tcp",</span><br><span style="color: hsl(120, 100%, 40%);">+                                               current_string, results);</span><br><span style="color: hsl(120, 100%, 40%);">+                             }</span><br><span style="color: hsl(120, 100%, 40%);">+                             if (results != -1) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                  results = ip_identify_match_srv_lookup(identify, "_sips._tcp",</span><br><span style="color: hsl(120, 100%, 40%);">+                                              current_string, results);</span><br><span style="color: hsl(120, 100%, 40%);">+                             }</span><br><span>                    }</span><br><span>            }</span><br><span> </span><br><span>@@ -554,7 +564,14 @@</span><br><span> static void match_to_var_list_append(struct ast_variable **head, struct ast_ha *ha)</span><br><span> {</span><br><span>     char str[MAX_OBJECT_FIELD];</span><br><span style="color: hsl(0, 100%, 40%);">-     const char *addr = ast_strdupa(ast_sockaddr_stringify_addr(&ha->addr));</span><br><span style="color: hsl(120, 100%, 40%);">+        const char *addr;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (ast_sockaddr_port(&ha->addr)) {</span><br><span style="color: hsl(120, 100%, 40%);">+            addr = ast_strdupa(ast_sockaddr_stringify(&ha->addr));</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              addr = ast_strdupa(ast_sockaddr_stringify_addr(&ha->addr));</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  snprintf(str, MAX_OBJECT_FIELD, "%s%s/%s", ha->sense == AST_SENSE_ALLOW ? "!" : "",</span><br><span>                          addr, ast_sockaddr_stringify_addr(&ha->netmask));</span><br><span> </span><br><span>@@ -737,7 +754,13 @@</span><br><span>                 indent = CLI_INDENT_TO_SPACES(context->indent_level);</span><br><span> </span><br><span>                 for (match = ident->matches; match; match = match->next) {</span><br><span style="color: hsl(0, 100%, 40%);">-                        const char *addr = ast_sockaddr_stringify_addr(&match->addr);</span><br><span style="color: hsl(120, 100%, 40%);">+                  const char *addr;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                   if (ast_sockaddr_port(&match->addr)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                         addr = ast_sockaddr_stringify(&match->addr);</span><br><span style="color: hsl(120, 100%, 40%);">+                   } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                              addr = ast_sockaddr_stringify_addr(&match->addr);</span><br><span style="color: hsl(120, 100%, 40%);">+                      }</span><br><span> </span><br><span>                        ast_str_append(&context->output_buffer, 0, "%*s: %s%s/%d\n",</span><br><span>                                indent,</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/13312">change 13312</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/+/13312"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 13 </div>
<div style="display:none"> Gerrit-Change-Id: I256d5bd5d478b95f526e2f80ace31b690eebba92 </div>
<div style="display:none"> Gerrit-Change-Number: 13312 </div>
<div style="display:none"> Gerrit-PatchSet: 11 </div>
<div style="display:none"> Gerrit-Owner: Sean Bright <sean.bright@gmail.com> </div>
<div style="display:none"> Gerrit-Reviewer: Benjamin Keith Ford <bford@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Friendly Automation </div>
<div style="display:none"> Gerrit-Reviewer: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@sangoma.com> </div>
<div style="display:none"> Gerrit-Reviewer: Sean Bright <sean.bright@gmail.com> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>