Summary: | ASTERISK-17797: Coding error in find_subchannel_and_lock() | ||||
Reporter: | Jeff Waltz (jeffw) | Labels: | |||
Date Opened: | 2011-05-04 12:39:14 | Date Closed: | 2014-11-08 18:44:10.000-0600 | ||
Priority: | Minor | Regression? | No | ||
Status: | Closed/Complete | Components: | Channels/chan_mgcp | ||
Versions: | 1.8.3 | Frequency of Occurrence | |||
Related Issues: |
| ||||
Environment: | Attachments: | ||||
Description: | The function find_subchannel_and_lock()in mgcp_chan.c has a coding error in two locations that prevent the subchannel from being found on non-dynamic gateways. This results in responses from half the gateways to be ignored. I built Asterisk from source on a Fedora 14 system. Here is the C code in question from Asterisk version 1.8.3.2: {code} for (g = gateways ? gateways : find_realtime_gw(name, at, sin); g; g = g->next ? g->next : find_realtime_gw(name, at, sin)) { [lines omitted] /* not dynamic, check if the name matches */ } else if (name) { if (strcasecmp(g->name, at)) { >>>> error >>>> g = g->next; continue; } /* not dynamic, no name, check if the addr matches */ } else if (!name && sin) { if ((g->addr.sin_addr.s_addr != sin->sin_addr.s_addr) || (g->addr.sin_port != sin->sin_port)) { >>>> error >>>> if(!g->next) >>>> error >>>> g = find_realtime_gw(name, at, sin); >>>> error >>>> else >>>> error >>>> g = g->next; continue; } } else { continue; } {code} Since the "for" statement includes updating "g" from "g->next", the extra updates to "g" in the code above cause gateway entries to be skipped and responses from those gateways to continually exceed the maximum retry count. I hope this helps! Jeff Waltz ****** ADDITIONAL INFORMATION ****** I just downloaded the source for 1.8.4 and the erroneous code is still present. | ||||
Comments: | By: Jeff Waltz (jeffw) 2011-05-04 13:23:44 I loaded 1.8.3.3 not 1.8.4, to double check that the error is still present. By: Jeff Waltz (jeffw) 2011-06-02 15:22:03 Here is a diff of the changes I made to correct this problem: 1802d1801 < g = g->next; 1809,1812d1807 < if(!g->next) < g = find_realtime_gw(name, at, sin); < else < g = g->next; By: Nenad Kljajic (foundanswer) 2011-06-09 04:22:32.377-0500 For loop does not check for null pointer. 1776c1778 < for (g = gateways ? gateways : find_realtime_gw(name, at, sin); g; g = g->next ? g->next : find_realtime_gw(name, at, sin)) { --- > for (g = gateways ? gateways : find_realtime_gw(name, at, sin); g; g = g ? (g->next ? g->next : find_realtime_gw(name, at, sin)) : NULL ) { By: Matt Jordan (mjordan) 2014-11-08 18:44:10.122-0600 This was fixed by a patch provided by Xavier Hienne in ASTERISK-24500. |