diff --git a/src/edge.c b/src/edge.c
index f185b4fe..2eaae5d1 100644
--- a/src/edge.c
+++ b/src/edge.c
@@ -110,11 +110,13 @@ bool dump_edges(connection_t *c) {
 	for splay_each(node_t, n, node_tree) {
 		for splay_each(edge_t, e, n->edge_tree) {
 			char *address = sockaddr2hostname(&e->address);
-			send_request(c, "%d %d %s %s %s %x %d",
+			char* local_address = sockaddr2hostname(&e->local_address);
+			send_request(c, "%d %d %s %s %s %s %x %d",
 					CONTROL, REQ_DUMP_EDGES,
 					e->from->name, e->to->name, address,
-					e->options, e->weight);
+					local_address, e->options, e->weight);
 			free(address);
+			free(local_address);
 		}
 	}
 
diff --git a/src/edge.h b/src/edge.h
index cbd9e5ac..ed46b8a4 100644
--- a/src/edge.h
+++ b/src/edge.h
@@ -30,6 +30,7 @@ typedef struct edge_t {
 	struct node_t *from;
 	struct node_t *to;
 	sockaddr_t address;
+	sockaddr_t local_address;
 
 	uint32_t options;                       /* options turned on for this edge */
 	int weight;                             /* weight of this edge */
diff --git a/src/protocol_auth.c b/src/protocol_auth.c
index b8d4ee8e..778c607b 100644
--- a/src/protocol_auth.c
+++ b/src/protocol_auth.c
@@ -822,6 +822,16 @@ bool ack_h(connection_t *c, const char *request) {
 	sockaddr2str(&c->address, &hisaddress, NULL);
 	c->edge->address = str2sockaddr(hisaddress, hisport);
 	free(hisaddress);
+	sockaddr_t local_sa;
+	socklen_t local_salen = sizeof local_sa;
+	if (getsockname(c->socket, &local_sa.sa, &local_salen) < 0)
+		logger(DEBUG_ALWAYS, LOG_WARNING, "Could not get local socket address for connection with %s", c->name);
+	else {
+		char *local_address;
+		sockaddr2str(&local_sa, &local_address, NULL);
+		c->edge->local_address = str2sockaddr(local_address, myport);
+		free(local_address);
+	}
 	c->edge->weight = (weight + c->estimated_weight) / 2;
 	c->edge->connection = c;
 	c->edge->options = c->options;
diff --git a/src/protocol_edge.c b/src/protocol_edge.c
index e285a6de..4760162c 100644
--- a/src/protocol_edge.c
+++ b/src/protocol_edge.c
@@ -37,14 +37,19 @@
 bool send_add_edge(connection_t *c, const edge_t *e) {
 	bool x;
 	char *address, *port;
+	char *local_address, *local_port;
 
 	sockaddr2str(&e->address, &address, &port);
+	sockaddr2str(&e->local_address, &local_address, &local_port);
 
-	x = send_request(c, "%d %x %s %s %s %s %x %d", ADD_EDGE, rand(),
+	x = send_request(c, "%d %x %s %s %s %s %x %d %s %s", ADD_EDGE, rand(),
 					 e->from->name, e->to->name, address, port,
-					 e->options, e->weight);
+					 e->options, e->weight, local_address, local_port);
+
 	free(address);
 	free(port);
+	free(local_address);
+	free(local_port);
 
 	return x;
 }
@@ -56,12 +61,15 @@ bool add_edge_h(connection_t *c, const char *request) {
 	char to_name[MAX_STRING_SIZE];
 	char to_address[MAX_STRING_SIZE];
 	char to_port[MAX_STRING_SIZE];
-	sockaddr_t address;
+	char address_local[MAX_STRING_SIZE] = "unknown";
+	char port_local[MAX_STRING_SIZE] = "unknown";
+	sockaddr_t address, local_address;
 	uint32_t options;
 	int weight;
 
-	if(sscanf(request, "%*d %*x "MAX_STRING" "MAX_STRING" "MAX_STRING" "MAX_STRING" %x %d",
-			  from_name, to_name, to_address, to_port, &options, &weight) != 6) {
+	int parameter_count = sscanf(request, "%*d %*x "MAX_STRING" "MAX_STRING" "MAX_STRING" "MAX_STRING" %x %d "MAX_STRING" "MAX_STRING,
+			                      from_name, to_name, to_address, to_port, &options, &weight, address_local, port_local);
+	if (parameter_count != 6 && parameter_count != 8) {
 		logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ADD_EDGE", c->name,
 			   c->hostname);
 		return false;
@@ -109,13 +117,14 @@ bool add_edge_h(connection_t *c, const char *request) {
 	/* Convert addresses */
 
 	address = str2sockaddr(to_address, to_port);
+	local_address = str2sockaddr(address_local, port_local);
 
 	/* Check if edge already exists */
 
 	e = lookup_edge(from, to);
 
 	if(e) {
-		if(e->weight != weight || e->options != options || sockaddrcmp(&e->address, &address)) {
+		if(e->weight != weight || e->options != options || sockaddrcmp(&e->address, &address) || sockaddrcmp(&e->local_address, &local_address)) {
 			if(from == myself) {
 				logger(DEBUG_PROTOCOL, LOG_WARNING, "Got %s from %s (%s) for ourself which does not match existing entry",
 						   "ADD_EDGE", c->name, c->hostname);
@@ -145,6 +154,7 @@ bool add_edge_h(connection_t *c, const char *request) {
 	e->from = from;
 	e->to = to;
 	e->address = address;
+	e->local_address = local_address;
 	e->options = options;
 	e->weight = weight;
 	edge_add(e);
diff --git a/src/tincctl.c b/src/tincctl.c
index da66c8ff..18fc05ac 100644
--- a/src/tincctl.c
+++ b/src/tincctl.c
@@ -985,6 +985,8 @@ static int cmd_dump(int argc, char *argv[]) {
 		char subnet[4096];
 		char host[4096];
 		char port[4096];
+		char local_host[4096];
+		char local_port[4096];
 		char via[4096];
 		char nexthop[4096];
 		int cipher, digest, maclength, compression, distance, socket, weight;
@@ -1025,8 +1027,8 @@ static int cmd_dump(int argc, char *argv[]) {
 			} break;
 
 			case REQ_DUMP_EDGES: {
-				int n = sscanf(line, "%*d %*d %s %s %s port %s %x %d", from, to, host, port, &options, &weight);
-				if(n != 6) {
+				int n = sscanf(line, "%*d %*d %s %s %s port %s %s port %s %x %d", from, to, host, port, local_host, local_port, &options, &weight);
+				if(n != 8) {
 					fprintf(stderr, "Unable to parse edge dump from tincd.\n");
 					return 1;
 				}
@@ -1038,7 +1040,7 @@ static int cmd_dump(int argc, char *argv[]) {
 					else if(do_graph == 2)
 						printf(" %s -> %s [w = %f, weight = %f];\n", node1, node2, w, w);
 				} else {
-					printf("%s to %s at %s port %s options %x weight %d\n", from, to, host, port, options, weight);
+					printf("%s to %s at %s port %s local %s port %s options %x weight %d\n", from, to, host, port, local_host, local_port, options, weight);
 				}
 			} break;