diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index d9bd552a107cfb0182258f1e3f15907d9c9c1289..2ed8a3692f0217390241c2c1eb5924f61d3b23c5 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -1206,10 +1206,10 @@ static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
 {
 	struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
 	if (new) {
-		size_t mallocd_datalen = new->mallocd_datalen;
+		size_t afdatalen = new->afdatalen;
 		memcpy(new, fr, sizeof(*new));
 		iax_frame_wrap(new, &fr->af);
-		new->mallocd_datalen = mallocd_datalen;
+		new->afdatalen = afdatalen;
 		new->data = NULL;
 		new->datalen = 0;
 		new->direction = DIRECTION_INGRESS;
@@ -4045,7 +4045,9 @@ static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned in
 	int sendmini=0;
 	unsigned int lastsent;
 	unsigned int fts;
-		
+
+	frb.fr2.afdatalen = sizeof(frb.buffer);
+
 	if (!pvt) {
 		ast_log(LOG_WARNING, "No private structure for packet?\n");
 		return -1;
@@ -6847,6 +6849,7 @@ static int socket_process(struct iax2_thread *thread)
 	/* allocate an iax_frame with 4096 bytes of data buffer */
 	fr = alloca(sizeof(*fr) + 4096);
 	fr->callno = 0;
+	fr->afdatalen = 4096; /* From alloca() above */
 
 	/* Copy frequently used parameters to the stack */
 	res = thread->buf_len;
diff --git a/channels/iax2-parser.c b/channels/iax2-parser.c
index 7947c7fc3b60bb32099582a5b80909da49f3267e..7695051933deb496be0b55de8463e29586c26d36 100644
--- a/channels/iax2-parser.c
+++ b/channels/iax2-parser.c
@@ -974,13 +974,20 @@ void iax_frame_wrap(struct iax_frame *fr, struct ast_frame *f)
 	fr->af.data = fr->afdata;
 	fr->af.len = f->len;
 	if (fr->af.datalen) {
+		size_t copy_len = fr->af.datalen;
+		if (copy_len > fr->afdatalen) {
+			ast_log(LOG_ERROR, "Losing frame data because destination buffer size '%d' bytes not big enough for '%d' bytes in the frame\n",
+				(int) fr->afdatalen, (int) fr->af.datalen);
+			copy_len = fr->afdatalen;
+		}
 #if __BYTE_ORDER == __LITTLE_ENDIAN
 		/* We need to byte-swap slinear samples from network byte order */
 		if ((fr->af.frametype == AST_FRAME_VOICE) && (fr->af.subclass == AST_FORMAT_SLINEAR)) {
-			ast_swapcopy_samples(fr->af.data, f->data, fr->af.samples);
+			/* 2 bytes / sample for SLINEAR */
+			ast_swapcopy_samples(fr->af.data, f->data, copy_len / 2);
 		} else
 #endif
-		memcpy(fr->af.data, f->data, fr->af.datalen);
+			memcpy(fr->af.data, f->data, copy_len);
 	}
 }
 
@@ -994,11 +1001,11 @@ struct iax_frame *iax_frame_new(int direction, int datalen, unsigned int cacheab
 	/* Attempt to get a frame from this thread's cache */
 	if ((iax_frames = ast_threadstorage_get(&frame_cache, sizeof(*iax_frames)))) {
 		AST_LIST_TRAVERSE_SAFE_BEGIN(iax_frames, fr, list) {
-			if (fr->mallocd_datalen >= datalen) {
-				size_t mallocd_datalen = fr->mallocd_datalen;
+			if (fr->afdatalen >= datalen) {
+				size_t afdatalen = fr->afdatalen;
 				AST_LIST_REMOVE_CURRENT(iax_frames, list);
 				memset(fr, 0, sizeof(*fr));
-				fr->mallocd_datalen = mallocd_datalen;
+				fr->afdatalen = afdatalen;
 				break;
 			}
 		}
@@ -1007,12 +1014,12 @@ struct iax_frame *iax_frame_new(int direction, int datalen, unsigned int cacheab
 	if (!fr) {
 		if (!(fr = ast_calloc_cache(1, sizeof(*fr) + datalen)))
 			return NULL;
-		fr->mallocd_datalen = datalen;
+		fr->afdatalen = datalen;
 	}
 #else
 	if (!(fr = ast_calloc(1, sizeof(*fr) + datalen)))
 		return NULL;
-	fr->mallocd_datalen = datalen;
+	fr->afdatalen = datalen;
 #endif
 
 
diff --git a/channels/iax2-parser.h b/channels/iax2-parser.h
index 076f7ca855d958367fb2558fc49fa17b9c09319e..e40669d3d4143b17955f2d9f935091bb0451829b 100644
--- a/channels/iax2-parser.h
+++ b/channels/iax2-parser.h
@@ -126,7 +126,7 @@ struct iax_frame {
 	/* Actual, isolated frame header */
 	struct ast_frame af;
 	/*! Amount of space _allocated_ for data */
-	size_t mallocd_datalen;
+	size_t afdatalen;
 	unsigned char unused[AST_FRIENDLY_OFFSET];
 	unsigned char afdata[0];	/* Data for frame */
 };