aboutsummaryrefslogtreecommitdiffstats
path: root/channels/chan_skinny.c
diff options
context:
space:
mode:
authorqwell <qwell@f38db490-d61c-443f-a65b-d21fe96a405b>2006-10-09 16:12:35 +0000
committerqwell <qwell@f38db490-d61c-443f-a65b-d21fe96a405b>2006-10-09 16:12:35 +0000
commitff0dee85be392095893ca0bffacbb4fcb498fde8 (patch)
treed26b46e1e4ebc7697f0ce6c069675ee5b4af8f54 /channels/chan_skinny.c
parentb55cc57edf8df6e0fc2ac56d7a567de7eae79507 (diff)
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: http://svn.digium.com/svn/asterisk/branches/1.4@44764 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels/chan_skinny.c')
-rw-r--r--channels/chan_skinny.c118
1 files changed, 70 insertions, 48 deletions
diff --git a/channels/chan_skinny.c b/channels/chan_skinny.c
index ec5a86be5..ae32ebf7b 100644
--- a/channels/chan_skinny.c
+++ b/channels/chan_skinny.c
@@ -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;
}
@@ -2153,54 +2210,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;
@@ -4173,13 +4182,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");