mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-11-04 05:15:22 +00:00 
			
		
		
		
	First pass at fixing REGISTER functionality under SIP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@799 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
		@@ -901,6 +901,7 @@ static int sip_hangup(struct ast_channel *ast)
 | 
			
		||||
{
 | 
			
		||||
	struct sip_pvt *p = ast->pvt->pvt;
 | 
			
		||||
	int needcancel = 0;
 | 
			
		||||
	int needdestroy = 0;
 | 
			
		||||
	if (option_debug)
 | 
			
		||||
		ast_log(LOG_DEBUG, "sip_hangup(%s)\n", ast->name);
 | 
			
		||||
	if (!ast->pvt->pvt) {
 | 
			
		||||
@@ -924,7 +925,7 @@ static int sip_hangup(struct ast_channel *ast)
 | 
			
		||||
	p->owner = NULL;
 | 
			
		||||
	ast->pvt->pvt = NULL;
 | 
			
		||||
 | 
			
		||||
	p->needdestroy = 1;
 | 
			
		||||
	needdestroy = 1;
 | 
			
		||||
	/* Start the process if it's not already started */
 | 
			
		||||
	if (!p->alreadygone && strlen(p->initreq.data)) {
 | 
			
		||||
		if (needcancel) {
 | 
			
		||||
@@ -932,7 +933,7 @@ static int sip_hangup(struct ast_channel *ast)
 | 
			
		||||
				transmit_request_with_auth(p, "CANCEL", p->ocseq, 1);
 | 
			
		||||
				/* Actually don't destroy us yet, wait for the 487 on our original 
 | 
			
		||||
				   INVITE, but do set an autodestruct just in case. */
 | 
			
		||||
				p->needdestroy = 0;
 | 
			
		||||
				needdestroy = 0;
 | 
			
		||||
				sip_scheddestroy(p, 15000);
 | 
			
		||||
			} else
 | 
			
		||||
				transmit_response_reliable(p, "403 Forbidden", &p->initreq);
 | 
			
		||||
@@ -941,11 +942,13 @@ static int sip_hangup(struct ast_channel *ast)
 | 
			
		||||
				/* Send a hangup */
 | 
			
		||||
				transmit_request_with_auth(p, "BYE", 0, 1);
 | 
			
		||||
			} else {
 | 
			
		||||
				/* Note we will need a BYE when this all settles out */
 | 
			
		||||
				/* Note we will need a BYE when this all settles out
 | 
			
		||||
				   but we can't send one while we have "INVITE" outstanding. */
 | 
			
		||||
				p->pendingbye = 1;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	p->needdestroy = needdestroy;
 | 
			
		||||
	ast_pthread_mutex_unlock(&p->lock);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -1433,6 +1436,7 @@ static int sip_register(char *value, int lineno)
 | 
			
		||||
		if (secret)
 | 
			
		||||
			strncpy(reg->secret, secret, sizeof(reg->secret)-1);
 | 
			
		||||
		reg->expire = -1;
 | 
			
		||||
		reg->timeout =  -1;
 | 
			
		||||
		reg->refresh = default_expiry;
 | 
			
		||||
		reg->addr.sin_family = AF_INET;
 | 
			
		||||
		memcpy(®->addr.sin_addr, hp->h_addr, sizeof(®->addr.sin_addr));
 | 
			
		||||
@@ -2437,8 +2441,9 @@ static int sip_reregister(void *data)
 | 
			
		||||
{
 | 
			
		||||
	/* if we are here, we know that we need to reregister. */
 | 
			
		||||
	struct sip_registry *r=(struct sip_registry *)data;
 | 
			
		||||
	return sip_do_register(r);
 | 
			
		||||
	
 | 
			
		||||
	r->expire = -1;
 | 
			
		||||
	sip_do_register(r);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -2455,15 +2460,23 @@ static int sip_reg_timeout(void *data)
 | 
			
		||||
{
 | 
			
		||||
	/* if we are here, our registration timed out, so we'll just do it over */
 | 
			
		||||
	struct sip_registry *r=data;
 | 
			
		||||
	struct sip_pvt *p;
 | 
			
		||||
	int res;
 | 
			
		||||
	ast_pthread_mutex_lock(&r->lock);
 | 
			
		||||
	ast_log(LOG_NOTICE, "Registration timed out, trying again\n"); 
 | 
			
		||||
	ast_log(LOG_NOTICE, "Registration for '%s@%s' timed out, trying again\n", r->username, inet_ntoa(r->addr.sin_addr)); 
 | 
			
		||||
	if (r->call) {
 | 
			
		||||
		/* Unlink us, destroy old call.  Locking is not relevent here because all this happens
 | 
			
		||||
		   in the single SIP manager thread. */
 | 
			
		||||
		p = r->call;
 | 
			
		||||
		p->registry = NULL;
 | 
			
		||||
		r->call = NULL;
 | 
			
		||||
		p->needdestroy = 1;
 | 
			
		||||
	}
 | 
			
		||||
	r->regstate=REG_STATE_UNREGISTERED;
 | 
			
		||||
	/* cancel ourselves first!!! */
 | 
			
		||||
	/* ast_sched_del(sched,r->timeout); */
 | 
			
		||||
	r->timeout = -1;
 | 
			
		||||
	res=transmit_register(r, "REGISTER", NULL);
 | 
			
		||||
	ast_pthread_mutex_unlock(&r->lock);
 | 
			
		||||
	return res;
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int transmit_register(struct sip_registry *r, char *cmd, char *auth)
 | 
			
		||||
@@ -2481,25 +2494,32 @@ static int transmit_register(struct sip_registry *r, char *cmd, char *auth)
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	if (!(p=r->call)) {
 | 
			
		||||
		if (!r->callid_valid) {
 | 
			
		||||
		  build_callid(r->callid, sizeof(r->callid), __ourip);
 | 
			
		||||
		  r->callid_valid=1;
 | 
			
		||||
		}
 | 
			
		||||
		p=sip_alloc( r->callid, &r->addr, 0);
 | 
			
		||||
		p->outgoing = 1;
 | 
			
		||||
		r->call=p;
 | 
			
		||||
		p->registry=r;
 | 
			
		||||
		strncpy(p->peersecret, r->secret, sizeof(p->peersecret)-1);
 | 
			
		||||
		strncpy(p->peername, r->username, sizeof(p->peername)-1);
 | 
			
		||||
		strncpy(p->username, r->username, sizeof(p->username)-1);
 | 
			
		||||
	if (r->call) {
 | 
			
		||||
		ast_log(LOG_WARNING, "Already have a call??\n");
 | 
			
		||||
	}
 | 
			
		||||
	build_callid(r->callid, sizeof(r->callid), __ourip);
 | 
			
		||||
	p=sip_alloc( r->callid, &r->addr, 0);
 | 
			
		||||
	if (!p) {
 | 
			
		||||
		ast_log(LOG_WARNING, "Unable to allocate registration call\n");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	p->outgoing = 1;
 | 
			
		||||
	r->call=p;
 | 
			
		||||
	p->registry=r;
 | 
			
		||||
	strncpy(p->peersecret, r->secret, sizeof(p->peersecret)-1);
 | 
			
		||||
	strncpy(p->peername, r->username, sizeof(p->peername)-1);
 | 
			
		||||
	strncpy(p->username, r->username, sizeof(p->username)-1);
 | 
			
		||||
	strncpy(p->exten, r->contact, sizeof(p->exten) - 1);
 | 
			
		||||
	build_contact(p);
 | 
			
		||||
 | 
			
		||||
	/* set up a timeout */
 | 
			
		||||
	if (auth==NULL && !r->timeout)  {
 | 
			
		||||
	if (auth==NULL)  {
 | 
			
		||||
		if (r->timeout > -1) {
 | 
			
		||||
			ast_log(LOG_WARNING, "Still have a timeout, %d\n", r->timeout);
 | 
			
		||||
			ast_sched_del(sched, r->timeout);
 | 
			
		||||
		}
 | 
			
		||||
		r->timeout = ast_sched_add(sched, 10*1000, sip_reg_timeout, r);
 | 
			
		||||
		ast_log(LOG_NOTICE, "Scheduled a timeout # %d\n", r->timeout);
 | 
			
		||||
		ast_log(LOG_DEBUG, "Scheduled a timeout # %d\n", r->timeout);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	snprintf(from, sizeof(from), "<sip:%s@%s>;tag=as%08x", r->username, inet_ntoa(r->addr.sin_addr), p->tag);
 | 
			
		||||
@@ -2516,11 +2536,6 @@ static int transmit_register(struct sip_registry *r, char *cmd, char *auth)
 | 
			
		||||
	add_header(&req, "Via", via);
 | 
			
		||||
	add_header(&req, "From", from);
 | 
			
		||||
	add_header(&req, "To", to);
 | 
			
		||||
	{
 | 
			
		||||
		char contact[256];
 | 
			
		||||
		snprintf(contact, sizeof(contact), "<sip:%s@%s:%d;transport=udp>", r->contact, inet_ntoa(p->ourip), ourport);
 | 
			
		||||
		add_header(&req, "Contact", contact);
 | 
			
		||||
	}
 | 
			
		||||
	add_header(&req, "Call-ID", p->callid);
 | 
			
		||||
	add_header(&req, "CSeq", tmp);
 | 
			
		||||
	add_header(&req, "User-Agent", "Asterisk PBX");
 | 
			
		||||
@@ -3816,19 +3831,23 @@ static void handle_response(struct sip_pvt *p, int resp, char *rest, struct sip_
 | 
			
		||||
				int expires;
 | 
			
		||||
				struct sip_registry *r;
 | 
			
		||||
				r=p->registry;
 | 
			
		||||
				r->regstate=REG_STATE_REGISTERED;
 | 
			
		||||
				ast_log(LOG_NOTICE, "Registration successful\n");
 | 
			
		||||
				ast_log(LOG_NOTICE, "Cancelling timeout %d\n", r->timeout);
 | 
			
		||||
				if (r->timeout) 
 | 
			
		||||
					ast_sched_del(sched, r->timeout);
 | 
			
		||||
				r->timeout=0;
 | 
			
		||||
				/* set us up for re-registering */
 | 
			
		||||
				/* figure out how long we got registered for */
 | 
			
		||||
				if (r->expire != -1)
 | 
			
		||||
					ast_sched_del(sched, r->expire);
 | 
			
		||||
				expires=atoi(get_header(req, "expires"));
 | 
			
		||||
				if (!expires) expires=default_expiry;
 | 
			
		||||
					r->expire=ast_sched_add(sched, (expires-2)*1000, sip_reregister, r); 
 | 
			
		||||
				if (r) {
 | 
			
		||||
					r->regstate=REG_STATE_REGISTERED;
 | 
			
		||||
					ast_log(LOG_NOTICE, "Registration successful\n");
 | 
			
		||||
					if (r->timeout > -1) {
 | 
			
		||||
						ast_log(LOG_DEBUG, "Cancelling timeout %d\n", r->timeout);
 | 
			
		||||
						ast_sched_del(sched, r->timeout);
 | 
			
		||||
					}
 | 
			
		||||
					r->timeout=-1;
 | 
			
		||||
					/* set us up for re-registering */
 | 
			
		||||
					/* figure out how long we got registered for */
 | 
			
		||||
					if (r->expire > -1)
 | 
			
		||||
						ast_sched_del(sched, r->expire);
 | 
			
		||||
					expires=atoi(get_header(req, "expires"));
 | 
			
		||||
					if (!expires) expires=default_expiry;
 | 
			
		||||
						r->expire=ast_sched_add(sched, (expires-2)*1000, sip_reregister, r); 
 | 
			
		||||
				} else
 | 
			
		||||
					ast_log(LOG_WARNING, "Got 200 OK on REGISTER that isn't a register\n");
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
			break;
 | 
			
		||||
@@ -4475,10 +4494,13 @@ static void *do_monitor(void *data)
 | 
			
		||||
restartsearch:		
 | 
			
		||||
		sip = iflist;
 | 
			
		||||
		while(sip) {
 | 
			
		||||
			ast_pthread_mutex_lock(&sip->lock);
 | 
			
		||||
			if (sip->needdestroy && !sip->packets) {
 | 
			
		||||
				ast_pthread_mutex_unlock(&sip->lock);
 | 
			
		||||
				__sip_destroy(sip, 1);
 | 
			
		||||
				goto restartsearch;
 | 
			
		||||
			}
 | 
			
		||||
			ast_pthread_mutex_unlock(&sip->lock);
 | 
			
		||||
			sip = sip->next;
 | 
			
		||||
		}
 | 
			
		||||
		ast_pthread_mutex_unlock(&iflock);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user