]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Merged revisions 44764 via svnmerge from
authorJason Parker <jparker@digium.com>
Mon, 9 Oct 2006 16:15:16 +0000 (16:15 +0000)
committerJason Parker <jparker@digium.com>
Mon, 9 Oct 2006 16:15:16 +0000 (16:15 +0000)
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r44764 | qwell | 2006-10-09 11:12:35 -0500 (Mon, 09 Oct 2006) | 4 lines

Fix a problem where phones that go "missing" never got unregistered.

Issue #8067, reported by pj, patch by Anthony LaMantia (with minor whitespace modifications)

........

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

channels/chan_skinny.c

index e6444cf27b867bbd7958a0f68d7670c7eb579697..20b7152631ff9d39ff010540082ec50deae85595 100644 (file)
@@ -1335,6 +1335,55 @@ static int codec_ast2skinny(int astcodec)
        }
 }
 
+
+static int skinny_register(struct skinny_req *req, struct skinnysession *s)
+{
+       struct skinny_device *d;
+       struct sockaddr_in sin;
+       socklen_t slen;
+
+       ast_mutex_lock(&devicelock);
+       for (d = devices; d; d = d->next) {
+               if (!strcasecmp(req->data.reg.name, d->id)
+                               && ast_apply_ha(d->ha, &(s->sin))) {
+                       s->device = d;
+                       d->type = letohl(req->data.reg.type);
+                       if (ast_strlen_zero(d->version_id)) {
+                               ast_copy_string(d->version_id, version_id, sizeof(d->version_id));
+                       }
+                       d->registered = 1;
+                       d->session = s;
+
+                       slen = sizeof(sin);
+                       if (getsockname(s->fd, (struct sockaddr *)&sin, &slen)) {
+                               ast_log(LOG_WARNING, "Cannot get socket name\n");
+                               sin.sin_addr = __ourip;
+                       }
+                       d->ourip = sin.sin_addr;
+                       break;
+               }
+       }
+       ast_mutex_unlock(&devicelock);
+       if (!d) {
+               return 0;
+       }
+       return 1;
+}
+
+static int skinny_unregister(struct skinny_req *req, struct skinnysession *s)
+{
+       struct skinny_device *d;
+
+       d = s->device;
+
+       if (d) {
+               d->session = NULL;
+               d->registered = 0;
+       }
+
+       return -1; /* main loop will destroy the session */
+}
+
 static int transmit_response(struct skinnysession *s, struct skinny_req *req)
 {
        int res = 0;
@@ -1350,9 +1399,17 @@ static int transmit_response(struct skinnysession *s, struct skinny_req *req)
        memcpy(s->outbuf+skinny_header_size, &req->data, sizeof(union skinny_data));
 
        res = write(s->fd, s->outbuf, letohl(req->len)+8);
+
        if (res != letohl(req->len)+8) {
                ast_log(LOG_WARNING, "Transmit: write only sent %d out of %d bytes: %s\n", res, letohl(req->len)+8, strerror(errno));
+               if (res == -1) {
+                       if (skinnydebug)
+                               ast_log(LOG_WARNING, "Transmit: Skinny Client was lost, unregistering\n");
+                       skinny_unregister(NULL, s);
+               }
+               
        }
+       
        ast_mutex_unlock(&s->lock);
        return 1;
 }
@@ -2128,54 +2185,6 @@ static struct skinny_device *build_device(const char *cat, struct ast_variable *
        return d;
 }
 
-static int skinny_register(struct skinny_req *req, struct skinnysession *s)
-{
-       struct skinny_device *d;
-       struct sockaddr_in sin;
-       socklen_t slen;
-
-       ast_mutex_lock(&devicelock);
-       for (d = devices; d; d = d->next) {
-               if (!strcasecmp(req->data.reg.name, d->id)
-                               && ast_apply_ha(d->ha, &(s->sin))) {
-                       s->device = d;
-                       d->type = letohl(req->data.reg.type);
-                       if (ast_strlen_zero(d->version_id)) {
-                               ast_copy_string(d->version_id, version_id, sizeof(d->version_id));
-                       }
-                       d->registered = 1;
-                       d->session = s;
-
-                       slen = sizeof(sin);
-                       if (getsockname(s->fd, (struct sockaddr *)&sin, &slen)) {
-                               ast_log(LOG_WARNING, "Cannot get socket name\n");
-                               sin.sin_addr = __ourip;
-                       }
-                       d->ourip = sin.sin_addr;
-                       break;
-               }
-       }
-       ast_mutex_unlock(&devicelock);
-       if (!d) {
-               return 0;
-       }
-       return 1;
-}
-
-static int skinny_unregister(struct skinny_req *req, struct skinnysession *s)
-{
-       struct skinny_device *d;
-
-       d = s->device;
-
-       if (d) {
-               d->session = NULL;
-               d->registered = 0;
-       }
-
-       return -1; /* main loop will destroy the session */
-}
-
 static void start_rtp(struct skinny_subchannel *sub)
 {
        struct skinny_line *l = sub->parent;
@@ -4153,13 +4162,26 @@ static int get_input(struct skinnysession *s)
                res = read(s->fd, s->inbuf, 4);
                if (res < 0) {
                        ast_log(LOG_WARNING, "read() returned error: %s\n", strerror(errno));
+
+                       if (skinnydebug)
+                               ast_verbose("Skinny Client was lost, unregistering\n");
+             
+                       skinny_unregister(NULL,s);
                        ast_mutex_unlock(&s->lock);
                        return res;
                } else if (res != 4) {
                        ast_log(LOG_WARNING, "Skinny Client sent less data than expected.  Expected 4 but got %d.\n", res);
                        ast_mutex_unlock(&s->lock);
+                       
+                       if (res == 0) {
+                               if (skinnydebug)
+                                       ast_verbose("Skinny Client was lost, unregistering\n");
+                               skinny_unregister(NULL, s);
+                       }
+                    
                        return -1;
                }
+               
                dlen = letohl(*(int *)s->inbuf);
                if (dlen < 0) {
                        ast_log(LOG_WARNING, "Skinny Client sent invalid data.\n");