properly respond to REGISTER queries (issue #5272)
authorKevin P. Fleming <kpfleming@digium.com>
Mon, 26 Sep 2005 01:22:09 +0000 (01:22 +0000)
committerKevin P. Fleming <kpfleming@digium.com>
Mon, 26 Sep 2005 01:22:09 +0000 (01:22 +0000)
remove unused sip_peer expiry field

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

channels/chan_sip.c

index 0888b90..7daa1ee 100755 (executable)
@@ -726,7 +726,6 @@ struct sip_peer {
        unsigned int sipoptions;        /* Supported SIP options */
        struct ast_flags flags_page2;   /* SIP_PAGE2 flags */
        int expire;                     /* When to expire this peer registration */
-       int expiry;                     /* Duration of registration */
        int capability;                 /* Codec capability */
        int rtptimeout;                 /* RTP timeout */
        int rtpholdtimeout;             /* RTP Hold Timeout */
@@ -5513,8 +5512,14 @@ static int parse_ok_contact(struct sip_pvt *pvt, struct sip_request *req)
 }
 
 
-/*--- parse_contact: Parse contact header and save registration ---*/
-static int parse_contact(struct sip_pvt *pvt, struct sip_peer *p, struct sip_request *req)
+enum parse_register_result {
+       PARSE_REGISTER_FAILED,
+       PARSE_REGISTER_UPDATE,
+       PARSE_REGISTER_QUERY,
+};
+
+/*--- parse_register_contact: Parse contact header and save registration ---*/
+static enum parse_register_result parse_register_contact(struct sip_pvt *pvt, struct sip_peer *p, struct sip_request *req)
 {
        char contact[80]; 
        char data[256];
@@ -5550,7 +5555,19 @@ static int parse_contact(struct sip_pvt *pvt, struct sip_peer *p, struct sip_req
        }
        c = get_in_brackets(contact);
 
-       if (!strcasecmp(c, "*") || !expiry) {   /* Unregister this peer */
+       /* if they did not specify Contact: or Expires:, they are querying
+          what we currently have stored as their contact address, so return
+          it
+       */
+       if (ast_strlen_zero(c) && (!expires || ast_strlen_zero(expires))) {
+               if ((p->expire > -1) && !ast_strlen_zero(p->fullcontact)) {
+                       /* tell them when the registration is going to expire */
+                       pvt->expiry = ast_sched_when(sched, p->expire);
+                       return PARSE_REGISTER_QUERY;
+               } else {
+                       return PARSE_REGISTER_FAILED;
+               }
+       } else if (!strcasecmp(c, "*") || !expiry) {    /* Unregister this peer */
                /* This means remove all registrations and return OK */
                memset(&p->addr, 0, sizeof(p->addr));
                if (p->expire > -1)
@@ -5566,7 +5583,7 @@ static int parse_contact(struct sip_pvt *pvt, struct sip_peer *p, struct sip_req
                if (option_verbose > 2)
                        ast_verbose(VERBOSE_PREFIX_3 "Unregistered SIP '%s'\n", p->name);
                        manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Unregistered\r\n", p->name);
-               return 0;
+               return PARSE_REGISTER_UPDATE;
        }
        ast_copy_string(p->fullcontact, c, sizeof(p->fullcontact));
        /* For the 200 OK, we should use the received contact */
@@ -5603,7 +5620,7 @@ static int parse_contact(struct sip_pvt *pvt, struct sip_peer *p, struct sip_req
                hp = ast_gethostbyname(n, &ahp);
                if (!hp)  {
                        ast_log(LOG_WARNING, "Invalid host '%s'\n", n);
-                       return -1;
+                       return PARSE_REGISTER_FAILED;
                }
                p->addr.sin_family = AF_INET;
                memcpy(&p->addr.sin_addr, hp->h_addr, sizeof(p->addr.sin_addr));
@@ -5650,7 +5667,7 @@ static int parse_contact(struct sip_pvt *pvt, struct sip_peer *p, struct sip_req
                        ast_verbose(VERBOSE_PREFIX_3 "Saved useragent \"%s\" for peer %s\n",p->useragent,p->name);  
                }
        }
-       return 0;
+       return PARSE_REGISTER_UPDATE;
 }
 
 /*--- free_old_route: Remove route from route list ---*/
@@ -6100,14 +6117,22 @@ static int register_verify(struct sip_pvt *p, struct sockaddr_in *sin, struct si
                        transmit_response(p, "100 Trying", req);
                        if (!(res = check_auth(p, req, p->randdata, sizeof(p->randdata), peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, 0, ignore))) {
                                sip_cancel_destroy(p);
-                               if (parse_contact(p, peer, req)) {
+                               switch (parse_register_contact(p, peer, req)) {
+                               case PARSE_REGISTER_FAILED:
                                        ast_log(LOG_WARNING, "Failed to parse contact info\n");
-                               } else {
+                                       break;
+                               case PARSE_REGISTER_QUERY:
+                                       transmit_response_with_date(p, "200 OK", req);
+                                       peer->lastmsgssent = -1;
+                                       res = 0;
+                                       break;
+                               case PARSE_REGISTER_UPDATE:
                                        update_peer(peer, p->expiry);
                                        /* Say OK and ask subsystem to retransmit msg counter */
                                        transmit_response_with_date(p, "200 OK", req);
                                        peer->lastmsgssent = -1;
                                        res = 0;
+                                       break;
                                }
                        } 
                }
@@ -6119,14 +6144,22 @@ static int register_verify(struct sip_pvt *p, struct sockaddr_in *sin, struct si
                        ASTOBJ_CONTAINER_LINK(&peerl, peer);
                        peer->lastmsgssent = -1;
                        sip_cancel_destroy(p);
-                       if (parse_contact(p, peer, req)) {
+                       switch (parse_register_contact(p, peer, req)) {
+                       case PARSE_REGISTER_FAILED:
                                ast_log(LOG_WARNING, "Failed to parse contact info\n");
-                       } else {
+                               break;
+                       case PARSE_REGISTER_QUERY:
+                               transmit_response_with_date(p, "200 OK", req);
+                               peer->lastmsgssent = -1;
+                               res = 0;
+                               break;
+                       case PARSE_REGISTER_UPDATE:
                                /* Say OK and ask subsystem to retransmit msg counter */
-                               manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name);
                                transmit_response_with_date(p, "200 OK", req);
+                               manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "Peer: SIP/%s\r\nPeerStatus: Registered\r\n", peer->name);
                                peer->lastmsgssent = -1;
                                res = 0;
+                               break;
                        }
                }
        }
@@ -7543,7 +7576,6 @@ static int _sip_show_peer(int type, int fd, struct mansession *s, struct message
                ast_cli(fd, "  Dynamic      : %s\n", (ast_test_flag(peer, SIP_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, "  Expiry       : %d\n", peer->expiry);
                ast_cli(fd, "  Insecure     : %s\n", insecure2str(ast_test_flag(peer, SIP_INSECURE_PORT), ast_test_flag(peer, SIP_INSECURE_INVITE)));
                ast_cli(fd, "  Nat          : %s\n", nat2str(ast_test_flag(peer, SIP_NAT)));
                ast_cli(fd, "  ACL          : %s\n", (peer->ha?"Yes":"No"));
@@ -7618,7 +7650,6 @@ static int _sip_show_peer(int type, int fd, struct mansession *s, struct message
                ast_cli(fd, "Dynamic: %s\r\n", (ast_test_flag(peer, SIP_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, "RegExpiry: %d\r\n", peer->expiry);
                ast_cli(fd, "SIP-AuthInsecure: %s\r\n", insecure2str(ast_test_flag(peer, SIP_INSECURE_PORT), ast_test_flag(peer, SIP_INSECURE_INVITE)));
                ast_cli(fd, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(peer, SIP_NAT)));
                ast_cli(fd, "ACL: %s\r\n", (peer->ha?"Y":"N"));
@@ -11363,7 +11394,6 @@ static struct sip_peer *temp_peer(const char *name)
        strcpy(peer->musicclass, global_musicclass);
        peer->addr.sin_port = htons(DEFAULT_SIP_PORT);
        peer->addr.sin_family = AF_INET;
-       peer->expiry = expiry;
        peer->capability = global_capability;
        peer->rtptimeout = global_rtptimeout;
        peer->rtpholdtimeout = global_rtpholdtimeout;
@@ -11425,7 +11455,6 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, int
                peer->addr.sin_port = htons(DEFAULT_SIP_PORT);
                peer->addr.sin_family = AF_INET;
                peer->defaddr.sin_family = AF_INET;
-               peer->expiry = expiry;
        }
        /* If we have channel variables, remove them (reload) */
        if (peer->chanvars) {