]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
automerge commit
authorAutomerge script <automerge@asterisk.org>
Wed, 24 May 2006 21:05:13 +0000 (21:05 +0000)
committerAutomerge script <automerge@asterisk.org>
Wed, 24 May 2006 21:05:13 +0000 (21:05 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.2-netsec@30097 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_sip.c

index 25cde6be89749ed4528653a9ad1a0eaf1c58a5fe..b19a8d24fc7d69fcfc1ba12c128fab202e8acb0a 100644 (file)
@@ -534,7 +534,7 @@ struct sip_auth {
 #define SIP_USECLIENTCODE      (1 << 12)       /*!< Trust X-ClientCode info message */
 #define SIP_OUTGOING           (1 << 13)       /*!< Is this an outgoing call? */
 #define SIP_SELFDESTRUCT       (1 << 14)       /*!< This is an autocreated peer */
-#define SIP_DYNAMIC            (1 << 15)       /*!< Is this a dynamic peer? */
+#define SIP_CAN_BYE            (1 << 15)       /*!< Can we send BYE for this dialog? */
 /* --- Choices for DTMF support in SIP channel */
 #define SIP_DTMF               (3 << 16)       /*!< three settings, uses two bits */
 #define SIP_DTMF_RFC2833       (0 << 16)       /*!< RTP DTMF */
@@ -584,6 +584,7 @@ struct sip_auth {
 #define SIP_PAGE2_RTAUTOCLEAR          (1 << 2)
 #define SIP_PAGE2_IGNOREREGEXPIRE      (1 << 3)
 #define SIP_PAGE2_RT_FROMCONTACT       (1 << 4)
+#define SIP_PAGE2_DYNAMIC              (1 << 5)        /*!< Is this a dynamic peer? */
 
 /* SIP packet flags */
 #define SIP_PKT_DEBUG          (1 << 0)        /*!< Debug this packet */
@@ -2494,12 +2495,18 @@ static int sip_hangup(struct ast_channel *ast)
                                /* stop retransmitting an INVITE that has not received a response */
                                __sip_pretend_ack(p);
 
-                               /* Send a new request: CANCEL */
-                               transmit_request_with_auth(p, SIP_CANCEL, p->ocseq, 1, 0);
-                               /* Actually don't destroy us yet, wait for the 487 on our original 
-                                  INVITE, but do set an autodestruct just in case we never get it. */
-                               ast_clear_flag(&locflags, SIP_NEEDDESTROY);
-                               sip_scheddestroy(p, 32000);
+                               /* are we allowed to send CANCEL yet? if not, mark
+                                  it pending */
+                               if (!ast_test_flag(p, SIP_CAN_BYE)) {
+                                       ast_set_flag(p, SIP_PENDINGBYE);
+                               } else {
+                                       /* Send a new request: CANCEL */
+                                       transmit_request_with_auth(p, SIP_CANCEL, p->ocseq, 1, 0);
+                                       /* Actually don't destroy us yet, wait for the 487 on our original 
+                                          INVITE, but do set an autodestruct just in case we never get it. */
+                                       ast_clear_flag(&locflags, SIP_NEEDDESTROY);
+                                       sip_scheddestroy(p, 32000);
+                               }
                                if ( p->initid != -1 ) {
                                        /* channel still up - reverse dec of inUse counter
                                           only if the channel is not auto-congested */
@@ -6582,7 +6589,7 @@ static int register_verify(struct sip_pvt *p, struct sockaddr_in *sin, struct si
                        ASTOBJ_UNREF(peer,sip_destroy_peer);
        }
        if (peer) {
-               if (!ast_test_flag(peer, SIP_DYNAMIC)) {
+               if (!ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC)) {
                        ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name);
                } else {
                        ast_copy_flags(p, peer, SIP_NAT);
@@ -7731,7 +7738,7 @@ static int _sip_show_peers(int fd, int *total, struct mansession *s, struct mess
                
                snprintf(srch, sizeof(srch), FORMAT, name,
                        iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "(Unspecified)",
-                       ast_test_flag(iterator, SIP_DYNAMIC) ? " D " : "   ",   /* Dynamic or not? */
+                       ast_test_flag(&iterator->flags_page2, SIP_PAGE2_DYNAMIC) ? " D " : "   ",       /* Dynamic or not? */
                        (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? " N " : "   ",     /* NAT=yes? */
                        iterator->ha ? " A " : "   ",   /* permit/deny */
                        ntohs(iterator->addr.sin_port), status);
@@ -7739,7 +7746,7 @@ static int _sip_show_peers(int fd, int *total, struct mansession *s, struct mess
                if (!s)  {/* Normal CLI list */
                        ast_cli(fd, FORMAT, name, 
                        iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "(Unspecified)",
-                       ast_test_flag(iterator, SIP_DYNAMIC) ? " D " : "   ",  /* Dynamic or not? */
+                       ast_test_flag(&iterator->flags_page2, SIP_PAGE2_DYNAMIC) ? " D " : "   ",  /* Dynamic or not? */
                        (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? " N " : "   ",     /* NAT=yes? */
                        iterator->ha ? " A " : "   ",       /* permit/deny */
                        
@@ -7761,7 +7768,7 @@ static int _sip_show_peers(int fd, int *total, struct mansession *s, struct mess
                        iterator->name, 
                        iterator->addr.sin_addr.s_addr ? ast_inet_ntoa(iabuf, sizeof(iabuf), iterator->addr.sin_addr) : "-none-",
                        ntohs(iterator->addr.sin_port), 
-                       ast_test_flag(iterator, SIP_DYNAMIC) ? "yes" : "no",  /* Dynamic or not? */
+                       ast_test_flag(&iterator->flags_page2, SIP_PAGE2_DYNAMIC) ? "yes" : "no",  /* Dynamic or not? */
                        (ast_test_flag(iterator, SIP_NAT) & SIP_NAT_ROUTE) ? "yes" : "no",      /* NAT=yes? */
                        iterator->ha ? "yes" : "no",       /* permit/deny */
                        status);
@@ -8134,7 +8141,7 @@ static int _sip_show_peer(int type, int fd, struct mansession *s, struct message
                ast_cli(fd, "  VM Extension : %s\n", peer->vmexten);
                ast_cli(fd, "  LastMsgsSent : %d\n", peer->lastmsgssent);
                ast_cli(fd, "  Call limit   : %d\n", peer->call_limit);
-               ast_cli(fd, "  Dynamic      : %s\n", (ast_test_flag(peer, SIP_DYNAMIC)?"Yes":"No"));
+               ast_cli(fd, "  Dynamic      : %s\n", (ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC)?"Yes":"No"));
                ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
                ast_cli(fd, "  Expire       : %d\n", peer->expire);
                ast_cli(fd, "  Insecure     : %s\n", insecure2str(ast_test_flag(peer, SIP_INSECURE_PORT), ast_test_flag(peer, SIP_INSECURE_INVITE)));
@@ -8206,7 +8213,7 @@ static int _sip_show_peer(int type, int fd, struct mansession *s, struct message
                ast_cli(fd, "VoiceMailbox: %s\r\n", peer->mailbox);
                ast_cli(fd, "LastMsgsSent: %d\r\n", peer->lastmsgssent);
                ast_cli(fd, "Call limit: %d\r\n", peer->call_limit);
-               ast_cli(fd, "Dynamic: %s\r\n", (ast_test_flag(peer, SIP_DYNAMIC)?"Y":"N"));
+               ast_cli(fd, "Dynamic: %s\r\n", (ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC)?"Y":"N"));
                ast_cli(fd, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, ""));
                ast_cli(fd, "RegExpire: %ld seconds\r\n", ast_sched_when(sched,peer->expire));
                ast_cli(fd, "SIP-AuthInsecure: %s\r\n", insecure2str(ast_test_flag(peer, SIP_INSECURE_PORT), ast_test_flag(peer, SIP_INSECURE_INVITE)));
@@ -9470,7 +9477,7 @@ static char *function_sippeer(struct ast_channel *chan, char *cmd, char *data, c
        } else  if (!strcasecmp(colname, "expire")) {
                snprintf(buf, len, "%d", peer->expire);
        } else  if (!strcasecmp(colname, "dynamic")) {
-               ast_copy_string(buf, (ast_test_flag(peer, SIP_DYNAMIC) ? "yes" : "no"), len);
+               ast_copy_string(buf, (ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC) ? "yes" : "no"), len);
        } else  if (!strcasecmp(colname, "callerid_name")) {
                ast_copy_string(buf, peer->cid_name, len);
        } else  if (!strcasecmp(colname, "callerid_num")) {
@@ -9630,11 +9637,18 @@ static void parse_moved_contact(struct sip_pvt *p, struct sip_request *req)
 /*! \brief  check_pendings: Check pending actions on SIP call ---*/
 static void check_pendings(struct sip_pvt *p)
 {
-       /* Go ahead and send bye at this point */
        if (ast_test_flag(p, SIP_PENDINGBYE)) {
-               transmit_request_with_auth(p, SIP_BYE, 0, 1, 1);
-               ast_set_flag(p, SIP_NEEDDESTROY);       
-               ast_clear_flag(p, SIP_NEEDREINVITE);    
+               /* if we can't BYE, then this is really a pending CANCEL */
+               if (!ast_test_flag(p, SIP_CAN_BYE)) {
+                       transmit_request_with_auth(p, SIP_CANCEL, p->ocseq, 1, 0);
+                       /* Actually don't destroy us yet, wait for the 487 on our original 
+                          INVITE, but do set an autodestruct just in case we never get it. */
+                       sip_scheddestroy(p, 32000);
+               } else {
+                       transmit_request_with_auth(p, SIP_BYE, 0, 1, 1);
+                       ast_set_flag(p, SIP_NEEDDESTROY);       
+                       ast_clear_flag(p, SIP_NEEDREINVITE);    
+               }
        } else if (ast_test_flag(p, SIP_NEEDREINVITE)) {
                ast_log(LOG_DEBUG, "Sending pending reinvite on '%s'\n", p->callid);
                /* Didn't get to reinvite yet, so do it now */
@@ -9664,6 +9678,10 @@ static void handle_response_invite(struct sip_pvt *p, int resp, char *rest, stru
        switch (resp) {
        case 100:       /* Trying */
                sip_cancel_destroy(p);
+               /* must call check_pendings before setting CAN_BYE, so that
+                  if PENDINGBYE is set it will know to send CANCEL instead */
+               check_pendings(p);
+               ast_set_flag(p, SIP_CAN_BYE);
                break;
        case 180:       /* 180 Ringing */
                sip_cancel_destroy(p);
@@ -9679,6 +9697,10 @@ static void handle_response_invite(struct sip_pvt *p, int resp, char *rest, stru
                                ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
                        }
                }
+               /* must call check_pendings before setting CAN_BYE, so that
+                  if PENDINGBYE is set it will know to send CANCEL instead */
+               check_pendings(p);
+               ast_set_flag(p, SIP_CAN_BYE);
                break;
        case 183:       /* Session progress */
                sip_cancel_destroy(p);
@@ -9690,6 +9712,10 @@ static void handle_response_invite(struct sip_pvt *p, int resp, char *rest, stru
                                ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
                        }
                }
+               /* must call check_pendings before setting CAN_BYE, so that
+                  if PENDINGBYE is set it will know to send CANCEL instead */
+               check_pendings(p);
+               ast_set_flag(p, SIP_CAN_BYE);
                break;
        case 200:       /* 200 OK on invite - someone's answering our call */
                sip_cancel_destroy(p);
@@ -12261,7 +12287,7 @@ static struct sip_peer *temp_peer(const char *name)
        peer->rtpholdtimeout = global_rtpholdtimeout;
        peer->rtpkeepalive = global_rtpkeepalive;
        ast_set_flag(peer, SIP_SELFDESTRUCT);
-       ast_set_flag(peer, SIP_DYNAMIC);
+       ast_set_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC);
        peer->prefs = prefs;
        reg_source_db(peer);
 
@@ -12392,7 +12418,7 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int
                                        ast_log(LOG_WARNING, "You can't have a dynamic outbound proxy, you big silly head at line %d.\n", v->lineno);
                                } else {
                                        /* They'll register with us */
-                                       ast_set_flag(peer, SIP_DYNAMIC);
+                                       ast_set_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC);
                                        if (!found) {
                                                /* Initialize stuff iff we're not found, otherwise
                                                   we keep going with what we had */
@@ -12409,7 +12435,7 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int
                                if (peer->expire > -1)
                                        ast_sched_del(sched, peer->expire);
                                peer->expire = -1;
-                               ast_clear_flag(peer, SIP_DYNAMIC);      
+                               ast_clear_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC);  
                                if (!obproxyfound || !strcasecmp(v->name, "outboundproxy")) {
                                        if (ast_get_ip_or_srv(&peer->addr, v->value, "_sip._udp")) {
                                                ASTOBJ_UNREF(peer, sip_destroy_peer);
@@ -12432,7 +12458,7 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int
                } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) {
                        peer->ha = ast_append_ha(v->name, v->value, peer->ha);
                } else if (!strcasecmp(v->name, "port")) {
-                       if (!realtime && ast_test_flag(peer, SIP_DYNAMIC))
+                       if (!realtime && ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC))
                                peer->defaddr.sin_port = htons(atoi(v->value));
                        else
                                peer->addr.sin_port = htons(atoi(v->value));
@@ -12514,7 +12540,7 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int
                 */
                v=v->next;
        }
-       if (!ast_test_flag((&global_flags_page2), SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(peer, SIP_DYNAMIC) && realtime) {
+       if (!ast_test_flag((&global_flags_page2), SIP_PAGE2_IGNOREREGEXPIRE) && ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC) && realtime) {
                time_t nowtime;
 
                time(&nowtime);
@@ -12526,7 +12552,7 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int
                }
        }
        ast_copy_flags(peer, &peerflags, mask.flags);
-       if (!found && ast_test_flag(peer, SIP_DYNAMIC) && !ast_test_flag(peer, SIP_REALTIME))
+       if (!found && ast_test_flag(&peer->flags_page2, SIP_PAGE2_DYNAMIC) && !ast_test_flag(peer, SIP_REALTIME))
                reg_source_db(peer);
        ASTOBJ_UNMARK(peer);
        ast_free_ha(oldha);