diff -u -r asterisk.dist/channels/chan_iax2.c asterisk/channels/chan_iax2.c
--- asterisk.dist/channels/chan_iax2.c	2006-09-03 02:03:08.000000000 +0200
+++ asterisk/channels/chan_iax2.c	2006-09-04 02:39:24.613340128 +0200
@@ -171,6 +171,7 @@
 static int timingfd = -1;				/* Timing file descriptor */
 
 static struct ast_netsock_list *netsock;
+static struct ast_netsock_list *outsock;		/* used if sourceaddress specified and bindaddr == INADDR_ANY */
 static int defaultsockfd = -1;
 
 static int usecnt = 0;
@@ -8185,20 +8186,42 @@
 		if (res == 0) {
 			/* ip address valid. */
 			sin.sin_port = htons(port);
-			sock = ast_netsock_find(netsock, &sin);
+			/* Stevenson! <stevens@stevens.it> - 2006/09/03 */
+			if (!(sock = ast_netsock_find(netsock, &sin))) {
+				sock = ast_netsock_find(outsock, &sin);
+			}
 			if (sock) {
 				sockfd = ast_netsock_sockfd(sock);
 				nonlocal = 0;
+			} else {
+				unsigned int orig_saddr = sin.sin_addr.s_addr;
+				/* INADDR_ANY matches anyway! */
+				sin.sin_addr.s_addr = INADDR_ANY;
+				if (ast_netsock_find(netsock, &sin)) {
+					sin.sin_addr.s_addr = orig_saddr;
+					sock = ast_netsock_bind(outsock, io, srcaddr, port, tos, socket_read, NULL);
+					if (sock) {
+						sockfd = ast_netsock_sockfd(sock);
+						ast_netsock_unref(sock);
+						nonlocal = 0;
+					} else {
+						nonlocal = 2;
+					}
+				}
 			}
 		}
 	}
 		
 	peer->sockfd = sockfd;
 
-	if (nonlocal) {
+	if (nonlocal == 1) {
 		ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n",
 			srcaddr, peer->name);
 		return -1;
+        } else if (nonlocal == 2) {
+		ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n",
+			srcaddr, peer->name);
+			return -1;
 	} else {
 		ast_log(LOG_DEBUG, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name);
 		return 0;
@@ -8959,7 +8982,17 @@
 			ast_netsock_unref(ns);
 		}
 	}
-	
+	/* Stevenson! <stevens@stevens.it> - 2006/09/04 */
+	if (reload) {
+		ast_netsock_release(outsock);
+		outsock = ast_netsock_list_alloc();
+		if (!outsock) {
+			ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
+			return -1;
+		}
+		ast_netsock_init(outsock);
+	}
+
 	if (min_reg_expire > max_reg_expire) {
 		ast_log(LOG_WARNING, "Minimum registration interval of %d is more than maximum of %d, resetting minimum to %d\n",
 			min_reg_expire, max_reg_expire, max_reg_expire);
@@ -9721,6 +9754,7 @@
         AST_LIST_UNLOCK(&dynamic_list);
 
 	ast_netsock_release(netsock);
+	ast_netsock_release(outsock);
 	for (x=0;x<IAX_MAX_CALLS;x++)
 		if (iaxs[x])
 			iax2_destroy(x);
@@ -9789,6 +9823,13 @@
 	}
 	ast_netsock_init(netsock);
 
+	outsock = ast_netsock_list_alloc();
+	if (!outsock) {
+		ast_log(LOG_ERROR, "Could not allocate outsock list.\n");
+		return -1;
+	}
+	ast_netsock_init(outsock);
+
 	ast_mutex_init(&waresl.lock);
 	
 	ast_cli_register_multiple(iax2_cli, sizeof(iax2_cli) / sizeof(iax2_cli[0]));
@@ -9817,6 +9858,7 @@
 	} else {
 		ast_log(LOG_ERROR, "Unable to start network thread\n");
 		ast_netsock_release(netsock);
+		ast_netsock_release(outsock);
 	}
 
 	for (reg = registrations; reg; reg = reg->next)
diff -u -r asterisk.dist/main/netsock.c asterisk/main/netsock.c
--- asterisk.dist/main/netsock.c	2006-08-23 20:14:46.000000000 +0200
+++ asterisk/main/netsock.c	2006-09-04 02:44:05.597627568 +0200
@@ -125,6 +125,8 @@
 	int *ioref;
 	
 	struct ast_netsock *ns;
+	const int reuseFlag = 1;
+	struct linger lng = { 1, 0 };
 	
 	/* Make a UDP socket */
 	netsocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
@@ -133,6 +135,12 @@
 		ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno));
 		return NULL;
 	}
+	if (setsockopt(netsocket, SOL_SOCKET, SO_REUSEADDR, (char *)&reuseFlag, sizeof reuseFlag) < 0) {
+			ast_log(LOG_WARNING, "Error setting SO_REUSEADDR on sockfd '%d'\n", netsocket);
+	}
+	if (setsockopt(netsocket, SOL_SOCKET, SO_LINGER, (char *)&lng, sizeof lng) < 0) {
+		ast_log(LOG_WARNING, "Error setting SO_LINGER on sockfd '%d'\n", netsocket);
+	}
 	if (bind(netsocket,(struct sockaddr *)bindaddr, sizeof(struct sockaddr_in))) {
 		ast_log(LOG_ERROR, "Unable to bind to %s port %d: %s\n", ast_inet_ntoa(bindaddr->sin_addr), ntohs(bindaddr->sin_port), strerror(errno));
 		close(netsocket);
