diff --exclude='*.o' --exclude='.*' -urN asterisk-cleanhead/channels/chan_iax2.c asterisk/channels/chan_iax2.c --- asterisk-cleanhead/channels/chan_iax2.c 2005-01-21 15:18:39.000000000 -0500 +++ asterisk/channels/chan_iax2.c 2005-01-21 15:19:22.000000000 -0500 @@ -5400,21 +5400,124 @@ return 0; } +static int handle_meta_rx(char *buf, int len, struct sockaddr_in sin, int fd) { + struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)buf; + struct ast_iax2_meta_trunk_hdr *mth; + struct ast_iax2_meta_trunk_entry *mte; + struct iax2_trunk_peer *tpeer; + char *ptr; + unsigned int ts; + int res=len, updatehistory=1; + char dblbuf[4096]; /* Declaration of dblbuf must immediately *preceed* fr on the stack */ + struct iax_frame fr; + char iabuf[INET_ADDRSTRLEN]; + struct ast_frame f; + struct timeval rxtrunktime; + + dblbuf[0]=0; + + /* This is a meta header */ + switch(meta->metacmd) { + case IAX_META_TRUNK: + if (res < sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr)) { + ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", res, (int)sizeof(struct ast_iax2_mini_hdr)); + return 1; + } + mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data); + ts = ntohl(mth->ts); + res -= (sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr)); + ptr = mth->data; + tpeer = find_tpeer(&sin, fd); + if (!tpeer) { + ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); + return 1; + } + if (!ts || (!tpeer->rxtrunktime.tv_sec && !tpeer->rxtrunktime.tv_usec)) { + gettimeofday(&tpeer->rxtrunktime, NULL); + tpeer->trunkact = tpeer->rxtrunktime; + } else + gettimeofday(&tpeer->trunkact, NULL); + rxtrunktime = tpeer->rxtrunktime; + ast_mutex_unlock(&tpeer->lock); + while(res >= sizeof(struct ast_iax2_meta_trunk_entry)) { + /* Process channels */ + mte = (struct ast_iax2_meta_trunk_entry *)ptr; + ptr += sizeof(struct ast_iax2_meta_trunk_entry); + res -= sizeof(struct ast_iax2_meta_trunk_entry); + len = ntohs(mte->len); + /* Stop if we don't have enough data */ + if (len > res) + break; + fr.callno = find_callno(ntohs(mte->callno) & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, 1, fd); + if (fr.callno) { + ast_mutex_lock(&iaxsl[fr.callno]); + /* If it's a valid call, deliver the contents. If not, we + drop it, since we don't have a scallno to use for an INVAL */ + /* Process as a mini frame */ + f.frametype = AST_FRAME_VOICE; + if (iaxs[fr.callno]) { + if (iaxs[fr.callno]->voiceformat > 0) { + f.subclass = iaxs[fr.callno]->voiceformat; + f.datalen = len; + if (f.datalen >= 0) { + if (f.datalen) + f.data = ptr; + else + f.data = NULL; + fr.ts = fix_peerts(&rxtrunktime, fr.callno, ts); + /* Don't pass any packets until we're started */ + if ((iaxs[fr.callno]->state & IAX_STATE_STARTED)) { + /* Common things */ + f.src = "IAX2"; + f.mallocd = 0; + f.offset = 0; + if (f.datalen && (f.frametype == AST_FRAME_VOICE)) + f.samples = get_samples(&f); + else + f.samples = 0; + fr.outoforder = 0; + iax_frame_wrap(&fr, &f); +#ifdef BRIDGE_OPTIMIZATION + if (iaxs[fr.callno]->bridgecallno) { + forward_delivery(&fr); + } else { + schedule_delivery(iaxfrdup2(&fr), 1, updatehistory, 1); + } +#else + schedule_delivery(iaxfrdup2(&fr), 1, updatehistory, 1); +#endif + } + } else { + ast_log(LOG_WARNING, "Datalen < 0?\n"); + } + } else { + ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n "); + iax2_vnak(fr.callno); + } + } + ast_mutex_unlock(&iaxsl[fr.callno]); + } + ptr += len; + res -= len; + } + + } + return 1; +} + static int socket_read(int *id, int fd, short events, void *cbdata) { struct sockaddr_in sin; int res; int updatehistory=1; int new = NEW_PREVENT; - char buf[4096], *ptr; + char buf[4096]; int len = sizeof(sin); int dcallno = 0; struct ast_iax2_full_hdr *fh = (struct ast_iax2_full_hdr *)buf; struct ast_iax2_mini_hdr *mh = (struct ast_iax2_mini_hdr *)buf; - struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)buf; struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)buf; - struct ast_iax2_meta_trunk_hdr *mth; - struct ast_iax2_meta_trunk_entry *mte; + struct ast_iax2_meta_hdr *meta = (struct ast_iax2_meta_hdr *)buf; char dblbuf[4096]; /* Declaration of dblbuf must immediately *preceed* fr on the stack */ struct iax_frame fr; struct iax_frame *cur; @@ -5423,14 +5526,11 @@ struct ast_channel *c; struct iax2_dpcache *dp; struct iax2_peer *peer; - struct iax2_trunk_peer *tpeer; - struct timeval rxtrunktime; struct iax_ies ies; struct iax_ie_data ied0, ied1; int format; int exists; int minivid = 0; - unsigned int ts; char empty[32]=""; /* Safety measure */ struct iax_frame *duped_fr; char host_pref_buf[128]; @@ -5457,93 +5557,7 @@ fr.callno = find_callno(ntohs(vh->callno) & ~0x8000, dcallno, &sin, new, 1, fd); minivid = 1; } else if (meta->zeros == 0) { - /* This is a meta header */ - switch(meta->metacmd) { - case IAX_META_TRUNK: - if (res < sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr)) { - ast_log(LOG_WARNING, "midget meta trunk packet received (%d of %d min)\n", res, (int)sizeof(struct ast_iax2_mini_hdr)); - return 1; - } - mth = (struct ast_iax2_meta_trunk_hdr *)(meta->data); - ts = ntohl(mth->ts); - res -= (sizeof(struct ast_iax2_meta_hdr) + sizeof(struct ast_iax2_meta_trunk_hdr)); - ptr = mth->data; - tpeer = find_tpeer(&sin, fd); - if (!tpeer) { - ast_log(LOG_WARNING, "Unable to accept trunked packet from '%s:%d': No matching peer\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port)); - return 1; - } - if (!ts || (!tpeer->rxtrunktime.tv_sec && !tpeer->rxtrunktime.tv_usec)) { - gettimeofday(&tpeer->rxtrunktime, NULL); - tpeer->trunkact = tpeer->rxtrunktime; - } else - gettimeofday(&tpeer->trunkact, NULL); - rxtrunktime = tpeer->rxtrunktime; - ast_mutex_unlock(&tpeer->lock); - while(res >= sizeof(struct ast_iax2_meta_trunk_entry)) { - /* Process channels */ - mte = (struct ast_iax2_meta_trunk_entry *)ptr; - ptr += sizeof(struct ast_iax2_meta_trunk_entry); - res -= sizeof(struct ast_iax2_meta_trunk_entry); - len = ntohs(mte->len); - /* Stop if we don't have enough data */ - if (len > res) - break; - fr.callno = find_callno(ntohs(mte->callno) & ~IAX_FLAG_FULL, 0, &sin, NEW_PREVENT, 1, fd); - if (fr.callno) { - ast_mutex_lock(&iaxsl[fr.callno]); - /* If it's a valid call, deliver the contents. If not, we - drop it, since we don't have a scallno to use for an INVAL */ - /* Process as a mini frame */ - f.frametype = AST_FRAME_VOICE; - if (iaxs[fr.callno]) { - if (iaxs[fr.callno]->voiceformat > 0) { - f.subclass = iaxs[fr.callno]->voiceformat; - f.datalen = len; - if (f.datalen >= 0) { - if (f.datalen) - f.data = ptr; - else - f.data = NULL; - fr.ts = fix_peerts(&rxtrunktime, fr.callno, ts); - /* Don't pass any packets until we're started */ - if ((iaxs[fr.callno]->state & IAX_STATE_STARTED)) { - /* Common things */ - f.src = "IAX2"; - f.mallocd = 0; - f.offset = 0; - if (f.datalen && (f.frametype == AST_FRAME_VOICE)) - f.samples = get_samples(&f); - else - f.samples = 0; - fr.outoforder = 0; - iax_frame_wrap(&fr, &f); -#ifdef BRIDGE_OPTIMIZATION - if (iaxs[fr.callno]->bridgecallno) { - forward_delivery(&fr); - } else { - schedule_delivery(iaxfrdup2(&fr), 1, updatehistory, 1); - } -#else - schedule_delivery(iaxfrdup2(&fr), 1, updatehistory, 1); -#endif - } - } else { - ast_log(LOG_WARNING, "Datalen < 0?\n"); - } - } else { - ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n "); - iax2_vnak(fr.callno); - } - } - ast_mutex_unlock(&iaxsl[fr.callno]); - } - ptr += len; - res -= len; - } - - } - return 1; + return handle_meta_rx(buf, len, sin, fd); } #ifdef DEBUG_SUPPORT if (iaxdebug)