diff --git a/apps/app_dial.c b/apps/app_dial.c
index 9199635381f5d2d67dce594292baff6f1e959e85..6a1022a7f0ab6da786ff032571ef51b656ebec61 100644
--- a/apps/app_dial.c
+++ b/apps/app_dial.c
@@ -1492,6 +1492,7 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags
 		
 		/* Inherit specially named variables from parent channel */
 		ast_channel_inherit_variables(chan, tc);
+		ast_channel_datastore_inherit(chan, tc);
 
 		tc->appl = "AppDial";
 		tc->data = "(Outgoing Line)";
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index 32ebe341be7339b6f48d8f88988e97defea27847..01f5ba62134a505a9f44ef8d3b346a4a18e45025 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -655,7 +655,10 @@ struct chan_iax2_pvt {
 	int calling_pres;
 	int amaflags;
 	AST_LIST_HEAD_NOLOCK(, iax2_dpcache) dpentries;
+	/*! variables inherited from the user definition */
 	struct ast_variable *vars;
+	/*! variables transmitted in a NEW packet */
+	struct ast_variable *iaxvars;
 	/*! last received remote rr */
 	struct iax_rr remote_rr;
 	/*! Current base time: (just for stats) */
@@ -3749,10 +3752,12 @@ static int iax2_call(struct ast_channel *c, char *dest, int timeout)
 	/* Add remote vars */
 	if (variablestore) {
 		AST_LIST_HEAD(, ast_var_t) *variablelist = variablestore->data;
+		ast_debug(1, "Found an IAX variable store on this channel\n");
 		AST_LIST_LOCK(variablelist);
 		AST_LIST_TRAVERSE(variablelist, var, entries) {
 			char tmp[256];
 			int i;
+			ast_debug(1, "Found IAXVAR '%s' with value '%s' (to transmit)\n", ast_var_name(var), ast_var_value(var));
 			/* Automatically divide the value up into sized chunks */
 			for (i = 0; i < strlen(ast_var_value(var)); i += 255 - (strlen(ast_var_name(var)) + 1)) {
 				snprintf(tmp, sizeof(tmp), "%s=%s", ast_var_name(var), ast_var_value(var) + i);
@@ -4258,6 +4263,42 @@ static struct ast_channel *ast_iax2_new(int callno, int state, int capability)
 		for (v = i->vars ; v ; v = v->next)
 			pbx_builtin_setvar_helper(tmp, v->name, v->value);
 	}
+	if (i->iaxvars) {
+		struct ast_datastore *variablestore;
+		struct ast_variable *var, *prev = NULL;
+		AST_LIST_HEAD(, ast_var_t) *varlist;
+		ast_debug(1, "Loading up the channel with IAXVARs\n");
+		varlist = ast_calloc(1, sizeof(*varlist));
+		variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
+		if (variablestore && varlist) {
+			variablestore->data = varlist;
+			variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
+			AST_LIST_HEAD_INIT(varlist);
+			for (var = i->iaxvars; var; var = var->next) {
+				struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
+				if (prev)
+					ast_free(prev);
+				prev = var;
+				if (!newvar) {
+					/* Don't abort list traversal, as this would leave i->iaxvars in an inconsistent state. */
+					ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
+				} else {
+					AST_LIST_INSERT_TAIL(varlist, newvar, entries);
+				}
+			}
+			if (prev)
+				ast_free(prev);
+			i->iaxvars = NULL;
+			ast_channel_datastore_add(i->owner, variablestore);
+		} else {
+			if (variablestore) {
+				ast_datastore_free(variablestore);
+			}
+			if (varlist) {
+				ast_free(varlist);
+			}
+		}
+	}
 
 	if (state != AST_STATE_DOWN) {
 		if (ast_pbx_start(tmp)) {
@@ -8344,8 +8385,10 @@ static int socket_process(struct iax2_thread *thread)
 				}
 				f.data.ptr = NULL;
 				f.datalen = 0;
-			} else
+			} else {
 				f.data.ptr = thread->buf + sizeof(*fh);
+				memset(&ies, 0, sizeof(ies));
+			}
 		} else {
 			if (f.frametype == AST_FRAME_IAX)
 				f.data.ptr = NULL;
@@ -8365,20 +8408,27 @@ static int socket_process(struct iax2_thread *thread)
 				if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat)) {
 					ast_mutex_unlock(&iaxsl[fr->callno]);
 					return 1;
-				} else if (ies.vars) {
-					struct ast_datastore *variablestore;
-					struct ast_variable *var, *prev = NULL;
-					AST_LIST_HEAD(, ast_var_t) *varlist;
+				}
+			}
+
+			if (ies.vars) {
+				struct ast_datastore *variablestore = NULL;
+				struct ast_variable *var, *prev = NULL;
+				AST_LIST_HEAD(, ast_var_t) *varlist;
+				if ((c = iaxs[fr->callno]->owner)) {
 					varlist = ast_calloc(1, sizeof(*varlist));
 					variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
+
 					if (variablestore && varlist) {
 						variablestore->data = varlist;
 						variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
 						AST_LIST_HEAD_INIT(varlist);
+						ast_debug(1, "I can haz IAX vars?\n");
 						for (var = ies.vars; var; var = var->next) {
 							struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
-							if (prev)
+							if (prev) {
 								ast_free(prev);
+							}
 							prev = var;
 							if (!newvar) {
 								/* Don't abort list traversal, as this would leave ies.vars in an inconsistent state. */
@@ -8387,19 +8437,36 @@ static int socket_process(struct iax2_thread *thread)
 								AST_LIST_INSERT_TAIL(varlist, newvar, entries);
 							}
 						}
-						if (prev)
+						if (prev) {
 							ast_free(prev);
+						}
 						ies.vars = NULL;
 						ast_channel_datastore_add(c, variablestore);
 					} else {
 						ast_log(LOG_ERROR, "Memory allocation error while processing IAX2 variables\n");
-						if (variablestore)
+						if (variablestore) {
 							ast_datastore_free(variablestore);
-						if (varlist)
+						}
+						if (varlist) {
 							ast_free(varlist);
+						}
+					}
+				} else {
+					/* No channel yet, so transfer the variables directly over to the pvt,
+					 * for later inheritance. */
+					ast_debug(1, "No channel, so populating IAXVARs to the pvt, as an intermediate step.\n");
+					for (var = ies.vars; var && var->next; var = var->next);
+					if (var) {
+						var->next = iaxs[fr->callno]->iaxvars;
+						iaxs[fr->callno]->iaxvars = ies.vars;
+						ies.vars = NULL;
 					}
 				}
 			}
+
+			if (ies.vars) {
+				ast_debug(1, "I have IAX variables, but they were not processed\n");
+			}
 		}
 
 		if (f.frametype == AST_FRAME_VOICE) {
@@ -8425,8 +8492,11 @@ retryowner:
 						} else {
 							ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n");
 							/* Free remote variables (if any) */
-							if (ies.vars)
+							if (ies.vars) {
 								ast_variables_destroy(ies.vars);
+								ast_debug(1, "I can haz iaxvars, but they is no good.  :-(\n");
+								ies.vars = NULL;
+							}
 							ast_mutex_unlock(&iaxsl[fr->callno]);
 							return 1;
 						}
@@ -9155,6 +9225,7 @@ retryowner2:
 									variablestore->data = varlist;
 									variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
 									AST_LIST_HEAD_INIT(varlist);
+									ast_debug(1, "I can haz IAX vars? w00t\n");
 									for (var = ies.vars; var; var = var->next) {
 										struct ast_var_t *newvar = ast_var_assign(var->name, var->value);
 										if (prev)
@@ -9215,6 +9286,7 @@ retryowner2:
 							AST_LIST_HEAD(, ast_var_t) *varlist;
 							varlist = ast_calloc(1, sizeof(*varlist));
 							variablestore = ast_datastore_alloc(&iax2_variable_datastore_info, NULL);
+							ast_debug(1, "I can haz IAX vars? w00t\n");
 							if (variablestore && varlist) {
 								variablestore->data = varlist;
 								variablestore->inheritance = DATASTORE_INHERIT_FOREVER;
@@ -9532,8 +9604,11 @@ retryowner2:
 				send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_UNSUPPORT, 0, ied0.buf, ied0.pos, -1);
 			}
 			/* Free remote variables (if any) */
-			if (ies.vars)
+			if (ies.vars) {
 				ast_variables_destroy(ies.vars);
+				ast_debug(1, "I can haz IAX vars, but they is no good :-(\n");
+				ies.vars = NULL;
+			}
 
 			/* Don't actually pass these frames along */
 			if ((f.subclass != IAX_COMMAND_ACK) && 
diff --git a/channels/iax2-parser.c b/channels/iax2-parser.c
index 34279223138050dfc59a8312d3d001ce0d47e072..b9af6fd6e546576f960a80434ba964cf2bdc598c 100644
--- a/channels/iax2-parser.c
+++ b/channels/iax2-parser.c
@@ -923,24 +923,32 @@ int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
 				*tmp2++ = '\0';
 			else
 				tmp2 = "";
-			/* Existing variable or new variable? */
-			for (var2 = ies->vars, prev = NULL; var2; prev = var2, var2 = var2->next) {
-				if (strcmp(tmp, var2->name) == 0) {
-					int length = strlen(var2->value) + strlen(tmp2) + 1;
-					char *tmp3 = alloca(length);
-					snprintf(tmp3, length, "%s%s", var2->value, tmp2);
-					var = ast_variable_new(tmp, tmp3, var2->file);
-					var->next = var2->next;
-					if (prev)
-						prev->next = var;
-					else
-						ies->vars = var;
-					ast_free(var2);
-					break;
+			{
+				struct ast_str *str = ast_str_create(16);
+				/* Existing variable or new variable? */
+				for (var2 = ies->vars, prev = NULL; var2; prev = var2, var2 = var2->next) {
+					if (strcmp(tmp, var2->name) == 0) {
+						ast_str_set(&str, 0, "%s%s", var2->value, tmp2);
+						var = ast_variable_new(tmp, str->str, var2->file);
+						var->next = var2->next;
+						if (prev) {
+							prev->next = var;
+						} else {
+							ies->vars = var;
+						}
+						snprintf(tmp, sizeof(tmp), "Assigned (%p)%s to (%p)%s\n", var->name, var->name, var->value, var->value);
+						errorf(tmp);
+						ast_free(var2);
+						break;
+					}
 				}
+				ast_free(str);
 			}
+
 			if (!var2) {
 				var = ast_variable_new(tmp, tmp2, "");
+				snprintf(tmp, sizeof(tmp), "Assigned (%p)%s to (%p)%s\n", var->name, var->name, var->value, var->value);
+				errorf(tmp);
 				var->next = ies->vars;
 				ies->vars = var;
 			}