@@ -1239,13 +1239,13 @@ static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
12391239#define NEW_ALLOW 1
12401240#define NEW_FORCE 2
12411241
1242- static int match (struct sockaddr_in * sin , unsigned short callno , unsigned short dcallno , struct chan_iax2_pvt * cur )
1242+ static int match (struct sockaddr_in * sin , unsigned short callno , unsigned short dcallno , struct chan_iax2_pvt * cur , int full_frame )
12431243{
12441244 if ((cur -> addr .sin_addr .s_addr == sin -> sin_addr .s_addr ) &&
12451245 (cur -> addr .sin_port == sin -> sin_port )) {
12461246 /* This is the main host */
1247- if ((cur -> peercallno == callno ) ||
1248- (( dcallno == cur -> callno ) && ! cur -> peercallno ) ) {
1247+ if ( (cur -> peercallno == 0 || cur -> peercallno == callno ) &&
1248+ ( full_frame ? dcallno == cur -> callno : 1 ) ) {
12491249 /* That's us. Be sure we keep track of the peer call number */
12501250 return 1 ;
12511251 }
@@ -1336,7 +1336,7 @@ static int make_trunk(unsigned short callno, int locked)
13361336/*!
13371337 * \note Calling this function while holding another pvt lock can cause a deadlock.
13381338 */
1339- static int __find_callno (unsigned short callno , unsigned short dcallno , struct sockaddr_in * sin , int new , int sockfd , int return_locked )
1339+ static int __find_callno (unsigned short callno , unsigned short dcallno , struct sockaddr_in * sin , int new , int sockfd , int return_locked , int full_frame )
13401340{
13411341 int res = 0 ;
13421342 int x ;
@@ -1349,7 +1349,7 @@ static int __find_callno(unsigned short callno, unsigned short dcallno, struct s
13491349 ast_mutex_lock (& iaxsl [x ]);
13501350 if (iaxs [x ]) {
13511351 /* Look for an exact match */
1352- if (match (sin , callno , dcallno , iaxs [x ])) {
1352+ if (match (sin , callno , dcallno , iaxs [x ], full_frame )) {
13531353 res = x ;
13541354 }
13551355 }
@@ -1359,14 +1359,16 @@ static int __find_callno(unsigned short callno, unsigned short dcallno, struct s
13591359 ast_mutex_lock (& iaxsl [x ]);
13601360 if (iaxs [x ]) {
13611361 /* Look for an exact match */
1362- if (match (sin , callno , dcallno , iaxs [x ])) {
1362+ if (match (sin , callno , dcallno , iaxs [x ], full_frame )) {
13631363 res = x ;
13641364 }
13651365 }
13661366 ast_mutex_unlock (& iaxsl [x ]);
13671367 }
13681368 }
13691369 if ((res < 1 ) && (new >= NEW_ALLOW )) {
1370+ int start , found = 0 ;
1371+
13701372 /* It may seem odd that we look through the peer list for a name for
13711373 * this *incoming* call. Well, it is weird. However, users don't
13721374 * have an IP address/port number that we can match against. So,
@@ -1375,15 +1377,29 @@ static int __find_callno(unsigned short callno, unsigned short dcallno, struct s
13751377 * correct, but it will be changed if needed after authentication. */
13761378 if (!iax2_getpeername (* sin , host , sizeof (host )))
13771379 snprintf (host , sizeof (host ), "%s:%d" , ast_inet_ntoa (sin -> sin_addr ), ntohs (sin -> sin_port ));
1378- gettimeofday (& now , NULL );
1379- for (x = 1 ;x < TRUNK_CALL_START ;x ++ ) {
1380+
1381+ now = ast_tvnow ();
1382+ start = 1 + (ast_random () % (TRUNK_CALL_START - 1 ));
1383+ for (x = start ; 1 ; x ++ ) {
1384+ if (x == TRUNK_CALL_START ) {
1385+ x = 0 ;
1386+ continue ;
1387+ }
1388+
13801389 /* Find first unused call number that hasn't been used in a while */
13811390 ast_mutex_lock (& iaxsl [x ]);
1382- if (!iaxs [x ] && ((now .tv_sec - lastused [x ].tv_sec ) > MIN_REUSE_TIME )) break ;
1391+ if (!iaxs [x ] && ((now .tv_sec - lastused [x ].tv_sec ) > MIN_REUSE_TIME )) {
1392+ found = 1 ;
1393+ break ;
1394+ }
13831395 ast_mutex_unlock (& iaxsl [x ]);
1396+
1397+ if (x == start - 1 ) {
1398+ break ;
1399+ }
13841400 }
13851401 /* We've still got lock held if we found a spot */
1386- if (x >= TRUNK_CALL_START ) {
1402+ if (x == start - 1 && ! found ) {
13871403 ast_log (LOG_WARNING , "No more space\n" );
13881404 return 0 ;
13891405 }
@@ -1420,14 +1436,14 @@ static int __find_callno(unsigned short callno, unsigned short dcallno, struct s
14201436 return res ;
14211437}
14221438
1423- static int find_callno (unsigned short callno , unsigned short dcallno , struct sockaddr_in * sin , int new , int sockfd ) {
1439+ static int find_callno (unsigned short callno , unsigned short dcallno , struct sockaddr_in * sin , int new , int sockfd , int full_frame ) {
14241440
1425- return __find_callno (callno , dcallno , sin , new , sockfd , 0 );
1441+ return __find_callno (callno , dcallno , sin , new , sockfd , 0 , full_frame );
14261442}
14271443
1428- static int find_callno_locked (unsigned short callno , unsigned short dcallno , struct sockaddr_in * sin , int new , int sockfd ) {
1444+ static int find_callno_locked (unsigned short callno , unsigned short dcallno , struct sockaddr_in * sin , int new , int sockfd , int full_frame ) {
14291445
1430- return __find_callno (callno , dcallno , sin , new , sockfd , 1 );
1446+ return __find_callno (callno , dcallno , sin , new , sockfd , 1 , full_frame );
14311447}
14321448
14331449static void iax2_frame_free (struct iax_frame * fr )
@@ -6871,7 +6887,7 @@ static int socket_process(struct iax2_thread *thread)
68716887 }
68726888
68736889 /* This is a video frame, get call number */
6874- fr -> callno = find_callno (ntohs (vh -> callno ) & ~0x8000 , dcallno , & sin , new , fd );
6890+ fr -> callno = find_callno (ntohs (vh -> callno ) & ~0x8000 , dcallno , & sin , new , fd , 0 );
68756891 minivid = 1 ;
68766892 } else if ((meta -> zeros == 0 ) && !(ntohs (meta -> metacmd ) & 0x8000 )) {
68776893 unsigned char metatype ;
@@ -6929,7 +6945,7 @@ static int socket_process(struct iax2_thread *thread)
69296945 /* Stop if we don't have enough data */
69306946 if (len > res )
69316947 break ;
6932- fr -> callno = find_callno_locked (callno & ~IAX_FLAG_FULL , 0 , & sin , NEW_PREVENT , fd );
6948+ fr -> callno = find_callno_locked (callno & ~IAX_FLAG_FULL , 0 , & sin , NEW_PREVENT , fd , 0 );
69336949 if (fr -> callno ) {
69346950 /* If it's a valid call, deliver the contents. If not, we
69356951 drop it, since we don't have a scallno to use for an INVAL */
@@ -7015,7 +7031,7 @@ static int socket_process(struct iax2_thread *thread)
70157031 }
70167032
70177033 if (!fr -> callno )
7018- fr -> callno = find_callno (ntohs (mh -> callno ) & ~IAX_FLAG_FULL , dcallno , & sin , new , fd );
7034+ fr -> callno = find_callno (ntohs (mh -> callno ) & ~IAX_FLAG_FULL , dcallno , & sin , new , fd , ntohs ( mh -> callno ) & IAX_FLAG_FULL );
70197035
70207036 if (fr -> callno > 0 )
70217037 ast_mutex_lock (& iaxsl [fr -> callno ]);
@@ -8510,7 +8526,7 @@ static int iax2_do_register(struct iax2_registry *reg)
85108526 if (!reg -> callno ) {
85118527 if (option_debug )
85128528 ast_log (LOG_DEBUG , "Allocate call number\n" );
8513- reg -> callno = find_callno_locked (0 , 0 , & reg -> addr , NEW_FORCE , defaultsockfd );
8529+ reg -> callno = find_callno_locked (0 , 0 , & reg -> addr , NEW_FORCE , defaultsockfd , 0 );
85148530 if (reg -> callno < 1 ) {
85158531 ast_log (LOG_WARNING , "Unable to create call for registration\n" );
85168532 return -1 ;
@@ -8571,7 +8587,7 @@ static int iax2_provision(struct sockaddr_in *end, int sockfd, char *dest, const
85718587 memset (& ied , 0 , sizeof (ied ));
85728588 iax_ie_append_raw (& ied , IAX_IE_PROVISIONING , provdata .buf , provdata .pos );
85738589
8574- callno = find_callno_locked (0 , 0 , & sin , NEW_FORCE , cai .sockfd );
8590+ callno = find_callno_locked (0 , 0 , & sin , NEW_FORCE , cai .sockfd , 0 );
85758591 if (!callno )
85768592 return -1 ;
85778593
@@ -8712,7 +8728,7 @@ static int iax2_poke_peer(struct iax2_peer *peer, int heldcall)
87128728 }
87138729 if (heldcall )
87148730 ast_mutex_unlock (& iaxsl [heldcall ]);
8715- peer -> callno = find_callno (0 , 0 , & peer -> addr , NEW_FORCE , peer -> sockfd );
8731+ peer -> callno = find_callno (0 , 0 , & peer -> addr , NEW_FORCE , peer -> sockfd , 0 );
87168732 if (heldcall )
87178733 ast_mutex_lock (& iaxsl [heldcall ]);
87188734 if (peer -> callno < 1 ) {
@@ -8792,7 +8808,7 @@ static struct ast_channel *iax2_request(const char *type, int format, void *data
87928808 if (pds .port )
87938809 sin .sin_port = htons (atoi (pds .port ));
87948810
8795- callno = find_callno_locked (0 , 0 , & sin , NEW_FORCE , cai .sockfd );
8811+ callno = find_callno_locked (0 , 0 , & sin , NEW_FORCE , cai .sockfd , 0 );
87968812 if (callno < 1 ) {
87978813 ast_log (LOG_WARNING , "Unable to create call\n" );
87988814 * cause = AST_CAUSE_CONGESTION ;
@@ -10106,7 +10122,7 @@ static int cache_get_callno_locked(const char *data)
1010610122 ast_log (LOG_DEBUG , "peer: %s, username: %s, password: %s, context: %s\n" ,
1010710123 pds .peer , pds .username , pds .password , pds .context );
1010810124
10109- callno = find_callno_locked (0 , 0 , & sin , NEW_FORCE , cai .sockfd );
10125+ callno = find_callno_locked (0 , 0 , & sin , NEW_FORCE , cai .sockfd , 0 );
1011010126 if (callno < 1 ) {
1011110127 ast_log (LOG_WARNING , "Unable to create call\n" );
1011210128 return -1 ;
0 commit comments