[asterisk-dev] [Fwd: [svn-commits] kpfleming: branch 1.4 r67270 - /branches/1.4/channels/chan_iax2.c]

Loic Didelot ldidelot at voipgate.com
Tue Jun 5 08:03:29 MST 2007


Hello,
I have no clue if this patch is somehow related to iax registrations,
but I applied the patch and flooded my server with one registration
every 10 ms and asterisk crashes after 10 seconds. I use a fast odbc
connection to a mysql database and the whole thing is running on a quite
up2date redhat entreprise system. 

Some people might say that it is normal as it is too many registrations.
Well the same test on SIP does not cause any problems to asterisk. 

So I wonder if those "flood" tests are done by the developers. If more
people see this problem I can send bugtraces to mantis. Or if Digium or
any other experienced IAX developer wants to have a look I can provide
them SSH access to my box.

Best regards,
Loic Didelot.



-------- Forwarded Message --------
> From: svn-commits at lists.digium.com
> To: asterisk-commits at lists.digium.com, svn-commits at lists.digium.com
> Subject: [svn-commits] kpfleming: branch 1.4 r67270
> - /branches/1.4/channels/chan_iax2.c
> Date: Tue, 05 Jun 2007 14:35:53 -0000
> 
> Author: kpfleming
> Date: Tue Jun  5 09:35:52 2007
> New Revision: 67270
> 
> URL: http://svn.digium.com/view/asterisk?view=rev&rev=67270
> Log:
> ensure that a burst of full frames (AST_FRAME_DTMF being the prime example) will not be processed out of order... this is a brute force fix, but seems to be the safest fix for now (thanks to the Digium PQ department for finding this bug)
> 
> 
> Modified:
>     branches/1.4/channels/chan_iax2.c
> 
> Modified: branches/1.4/channels/chan_iax2.c
> URL: http://svn.digium.com/view/asterisk/branches/1.4/channels/chan_iax2.c?view=diff&rev=67270&r1=67269&r2=67270
> ==============================================================================
> --- branches/1.4/channels/chan_iax2.c (original)
> +++ branches/1.4/channels/chan_iax2.c Tue Jun  5 09:35:52 2007
> @@ -703,6 +703,12 @@
>  	time_t checktime;
>  	ast_mutex_t lock;
>  	ast_cond_t cond;
> +	unsigned short ffcallno;		/* if this thread is processing a full frame, the
> +						   callno for that frame will be here, so we can
> +						   avoid dispatching any more full frames for that
> +						   callno to other threads */
> +	struct sockaddr_in ffsin;		/* remember the peer IP/port number for a full frame
> +						   in process */
>  };
>  
>  /* Thread lists */
> @@ -879,6 +885,11 @@
>  		}
>  		AST_LIST_UNLOCK(&dynamic_list);
>  	}
> +
> +	/* this thread is not processing a full frame (since it is idle),
> +	   so ensure that the field for the full frame call number is empty */
> +	thread->ffcallno = 0;
> +	memset(&thread->ffsin, 0, sizeof(thread->ffsin));
>  
>  	return thread;
>  }
> @@ -6260,37 +6271,68 @@
>  	struct iax2_thread *thread;
>  	socklen_t len;
>  	time_t t;
> -	static time_t last_errtime=0;
> -
> -	thread = find_idle_thread();
> -	if (thread) {
> -		len = sizeof(thread->iosin);
> -		thread->iofd = fd;
> -		thread->iores = recvfrom(fd, thread->buf, sizeof(thread->buf), 0,(struct sockaddr *) &thread->iosin, &len);
> -		if (thread->iores < 0) {
> -			if (errno != ECONNREFUSED && errno != EAGAIN)
> -				ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
> -			handle_error();
> -			insert_idle_thread(thread);
> -			return 1;
> -		}
> -		if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */
> -			insert_idle_thread(thread);
> -			return 1;
> -		}
> -		/* Mark as ready and send on its way */
> -		thread->iostate = IAX_IOSTATE_READY;
> -#ifdef DEBUG_SCHED_MULTITHREAD
> -		ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
> -#endif
> -		signal_condition(&thread->lock, &thread->cond);
> -	} else {
> +	static time_t last_errtime = 0;
> +	struct ast_iax2_full_hdr *fh;
> +
> +	if (!(thread = find_idle_thread())) {
>  		time(&t);
>  		if (t != last_errtime)
>  			ast_log(LOG_NOTICE, "Out of idle IAX2 threads for I/O, pausing!\n");
>  		last_errtime = t;
>  		usleep(1);
> -	}
> +		return 1;
> +	}
> +
> +	len = sizeof(thread->iosin);
> +	thread->iofd = fd;
> +	thread->iores = recvfrom(fd, thread->buf, sizeof(thread->buf), 0, (struct sockaddr *) &thread->iosin, &len);
> +	if (thread->iores < 0) {
> +		if (errno != ECONNREFUSED && errno != EAGAIN)
> +			ast_log(LOG_WARNING, "Error: %s\n", strerror(errno));
> +		handle_error();
> +		insert_idle_thread(thread);
> +		return 1;
> +	}
> +	if (test_losspct && ((100.0 * ast_random() / (RAND_MAX + 1.0)) < test_losspct)) { /* simulate random loss condition */
> +		insert_idle_thread(thread);
> +		return 1;
> +	}
> +	
> +	/* Determine if this frame is a full frame; if so, and any thread is currently
> +	   processing a full frame for the same callno from this peer, then drop this
> +	   frame (and the peer will retransmit it) */
> +	fh = (struct ast_iax2_full_hdr *) thread->buf;
> +	if (ntohs(fh->scallno) & IAX_FLAG_FULL) {
> +		struct iax2_thread *cur = NULL;
> +		
> +		AST_LIST_LOCK(&active_list);
> +		AST_LIST_TRAVERSE(&active_list, cur, list) {
> +			if ((cur->ffcallno == ntohs(fh->scallno)) &&
> +			    !memcmp(&cur->ffsin, &thread->iosin, sizeof(cur->ffsin)))
> +				break;
> +		}
> +		AST_LIST_UNLOCK(&active_list);
> +		if (cur) {
> +			/* we found another thread processing a full frame for this call,
> +			   so we can't accept this frame */
> +			ast_log(LOG_WARNING, "Dropping full frame from %s (callno %d) received too rapidly\n",
> +				ast_inet_ntoa(thread->iosin.sin_addr), cur->ffcallno);
> +			insert_idle_thread(thread);
> +			return 1;
> +		} else {
> +			/* this thread is going to process this frame, so mark it */
> +			thread->ffcallno = ntohs(fh->scallno);
> +			memcpy(&thread->ffsin, &thread->iosin, sizeof(thread->ffsin));
> +		}
> +	}
> +	
> +	/* Mark as ready and send on its way */
> +	thread->iostate = IAX_IOSTATE_READY;
> +#ifdef DEBUG_SCHED_MULTITHREAD
> +	ast_copy_string(thread->curfunc, "socket_process", sizeof(thread->curfunc));
> +#endif
> +	signal_condition(&thread->lock, &thread->cond);
> +
>  	return 1;
>  }
>  
> 
> _______________________________________________
> --Bandwidth and Colocation provided by Easynews.com --
> 
> svn-commits mailing list
> To UNSUBSCRIBE or update options visit:
>    http://lists.digium.com/mailman/listinfo/svn-commits
-- 
Loic DIDELOT (CTO)
voipGATE S.A.
Tel: +352 20 200 223
Fax: +352 20 200 923
E-mail: ldidelot at voipgate.com
Web: http://www.voipgate.com




More information about the asterisk-dev mailing list