]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Add option to not do a call forward on 482 Loop Detected
authorTerry Wilson <twilson@digium.com>
Tue, 6 Jul 2010 22:08:20 +0000 (22:08 +0000)
committerTerry Wilson <twilson@digium.com>
Tue, 6 Jul 2010 22:08:20 +0000 (22:08 +0000)
Asterisk has always set up a forwarded call when receiving a 482 Loop Detected.
This prevents handling the call failure by just continuing on in the dialplan.
Since this would be a change in behavior, the new option to disable this
behavior is forwardloopdetected which defaults to 'yes'.

Review: https://reviewboard.asterisk.org/r/764/

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@274280 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_sip.c
configs/sip.conf.sample

index f2585a487e715eb16dffe624074e4e69c73ca434..01742f8cf6a72b33c889fa6a16575c9f9b2c7a97 100644 (file)
@@ -812,11 +812,12 @@ struct sip_auth {
 #define SIP_PAGE2_UDPTL_DESTINATION     (1 << 28)       /*!< 28: Use source IP of RTP as destination if NAT is enabled */
 #define SIP_PAGE2_DIALOG_ESTABLISHED    (1 << 29)       /*!< 29: Has a dialog been established? */
 #define SIP_PAGE2_RPORT_PRESENT         (1 << 30)       /*!< 30: Was rport received in the Via header? */
+#define SIP_PAGE2_FORWARD_LOOP_DETECTED (1 << 31)       /*!< 31: Do call forward when receiving 482 Loop Detected */
 
 #define SIP_PAGE2_FLAGS_TO_COPY \
        (SIP_PAGE2_ALLOWSUBSCRIBE | SIP_PAGE2_ALLOWOVERLAP | SIP_PAGE2_VIDEOSUPPORT | \
        SIP_PAGE2_T38SUPPORT | SIP_PAGE2_RFC2833_COMPENSATE | SIP_PAGE2_BUGGY_MWI | \
-       SIP_PAGE2_UDPTL_DESTINATION)
+       SIP_PAGE2_UDPTL_DESTINATION | SIP_PAGE2_FORWARD_LOOP_DETECTED)
 
 /* SIP packet flags */
 #define SIP_PKT_DEBUG          (1 << 0)        /*!< Debug this packet */
@@ -11200,6 +11201,7 @@ static int _sip_show_peer(int type, int fd, struct mansession *s, const struct m
                ast_cli(fd, "  Send RPID    : %s\n", ast_test_flag(&peer->flags[0], SIP_SENDRPID) ? "Yes" : "No");
                ast_cli(fd, "  Subscriptions: %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE) ? "Yes" : "No");
                ast_cli(fd, "  Overlap dial : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP) ? "Yes" : "No");
+               ast_cli(fd, "  Forward Loop : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_FORWARD_LOOP_DETECTED) ? "Yes" : "No");
 
                /* - is enumerated */
                ast_cli(fd, "  DTMFmode     : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF)));
@@ -11503,7 +11505,7 @@ static int sip_show_settings(int fd, int argc, char *argv[])
        ast_cli(fd, "  MOH Interpret:          %s\n", default_mohinterpret);
        ast_cli(fd, "  MOH Suggest:            %s\n", default_mohsuggest);
        ast_cli(fd, "  Voice Mail Extension:   %s\n", default_vmexten);
-
+       ast_cli(fd, "  Forward Detected Loops: %s\n", (ast_test_flag(&global_flags[1], SIP_PAGE2_FORWARD_LOOP_DETECTED) ? "Yes" : "No"));
        
        if (realtimepeers || realtimeusers) {
                ast_cli(fd, "\nRealtime SIP Settings:\n");
@@ -13701,16 +13703,19 @@ static void handle_response(struct sip_pvt *p, int resp, char *rest, struct sip_
                                        if (p->owner)
                                                ast_queue_control(p->owner, AST_CONTROL_BUSY);
                                        break;
-                               case 482: /*
-                                       \note SIP is incapable of performing a hairpin call, which
-                                       is yet another failure of not having a layer 2 (again, YAY
-                                        IETF for thinking ahead).  So we treat this as a call
-                                        forward and hope we end up at the right place... */
-                                       if (option_debug)
-                                               ast_log(LOG_DEBUG, "Hairpin detected, setting up call forward for what it's worth\n");
-                                       if (p->owner)
+                               case 482: /* Loop Detected */
+                                       /*
+                                               \note Asterisk has historically tried to do a call forward when it
+                                               gets a 482, but that behavior isn't necessarily the best course of
+                                               action. Go ahead and do it anyway by default, but allow the option
+                                               to immediately pass to the next line in the dialplan. */
+                                       if (p->owner && ast_test_flag(&p->flags[1], SIP_PAGE2_FORWARD_LOOP_DETECTED)) {
+                                               if (option_debug) {
+                                                       ast_log(LOG_DEBUG, "Hairpin detected, setting up call forward for what it's worth\n");
+                                               }
                                                ast_string_field_build(p->owner, call_forward,
                                                                       "Local/%s@%s", p->username, p->context);
+                                       }
                                        /* Fall through */
                                case 480: /* Temporarily Unavailable */
                                case 404: /* Not Found */
@@ -17570,6 +17575,9 @@ static int handle_common_options(struct ast_flags *flags, struct ast_flags *mask
        } else if (!strcasecmp(v->name, "t38pt_usertpsource")) {
                ast_set_flag(&mask[1], SIP_PAGE2_UDPTL_DESTINATION);
                ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_UDPTL_DESTINATION);
+       } else if (!strcasecmp(v->name, "forwardloopdetected")) {
+               ast_set_flag(&mask[1], SIP_PAGE2_FORWARD_LOOP_DETECTED);
+               ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_FORWARD_LOOP_DETECTED);
        } else
                res = 0;
 
@@ -18386,6 +18394,7 @@ static int reload_config(enum channelreloadreason reason)
        ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833);                       /*!< Default DTMF setting: RFC2833 */
        ast_set_flag(&global_flags[0], SIP_NAT_RFC3581);                        /*!< NAT support if requested by device with rport */
        ast_set_flag(&global_flags[0], SIP_CAN_REINVITE);                       /*!< Allow re-invites */
+       ast_set_flag(&global_flags[1], SIP_PAGE2_FORWARD_LOOP_DETECTED); /*!< Set up call forward on 482 Loop Detected */
 
        /* Debugging settings, always default to off */
        dumphistory = FALSE;
index f0235bcd14c4dd607f816444d867d0b71ba467ee..10d401883bcabb60f770de8bb3001cb7a4de5dbd 100644 (file)
@@ -176,6 +176,9 @@ srvlookup=yes                   ; Enable DNS SRV lookups on outbound calls
 ;contactdeny=0.0.0.0/0.0.0.0           ; Use contactpermit and contactdeny to
 ;contactpermit=172.16.0.0/255.255.0.0  ; restrict at what IPs your users may
                                        ; register their phones.
+;forwardloopdetected=no         ; Attempt to forward a call locally if the
+                                ; destination replies with 482 Loop Detected
+                                ; default = yes
 
 ;
 ; If regcontext is specified, Asterisk will dynamically create and destroy a