Module Name:    src
Committed By:   kefren
Date:           Sat Jul 20 05:16:08 UTC 2013

Modified Files:
        src/usr.sbin/ldpd: fsm.c ldp_peer.c ldp_peer.h mpls_routes.c
            socketops.c tlv_stack.c

Log Message:
don't connect on first hello, there are chances that ours is not seen yet
setproctitle with ldp id - useful for rump kernels testing
fix a memory leak in ldp_peer_new
don't holddown if already holded down
peer sockets are now non-blocking
connected routes deletes are now processed
check if peer is connected before attempting to sending label mappings


To generate a diff of this commit:
cvs rdiff -u -r1.13 -r1.14 src/usr.sbin/ldpd/fsm.c
cvs rdiff -u -r1.14 -r1.15 src/usr.sbin/ldpd/ldp_peer.c
cvs rdiff -u -r1.6 -r1.7 src/usr.sbin/ldpd/ldp_peer.h
cvs rdiff -u -r1.18 -r1.19 src/usr.sbin/ldpd/mpls_routes.c
cvs rdiff -u -r1.29 -r1.30 src/usr.sbin/ldpd/socketops.c
cvs rdiff -u -r1.11 -r1.12 src/usr.sbin/ldpd/tlv_stack.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.sbin/ldpd/fsm.c
diff -u src/usr.sbin/ldpd/fsm.c:1.13 src/usr.sbin/ldpd/fsm.c:1.14
--- src/usr.sbin/ldpd/fsm.c:1.13	Fri Jul 12 08:55:52 2013
+++ src/usr.sbin/ldpd/fsm.c	Sat Jul 20 05:16:08 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: fsm.c,v 1.13 2013/07/12 08:55:52 kefren Exp $ */
+/* $NetBSD: fsm.c,v 1.14 2013/07/20 05:16:08 kefren Exp $ */
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -112,6 +112,7 @@ run_ldp_hello(const struct ldp_pdu * pdu
 		hi->ldp_id.s_addr = pduid->ldp_id.s_addr;
 		memcpy(&hi->transport_address, &traddr, traddr.sa.sa_len);
 		SLIST_INSERT_HEAD(&hello_info_head, hi, infos);
+		may_connect = false;
 	}
 
 	/* Update expire timer */
@@ -236,5 +237,6 @@ set_my_ldp_id()
 	freeifaddrs(ifa);
 	debugp("LDP ID: %s\n", inet_ntoa(a));
 	strlcpy(my_ldp_id, inet_ntoa(a), INET_ADDRSTRLEN);
+	setproctitle("LDP ID: %s", my_ldp_id);
 	return LDP_E_OK;
 }

Index: src/usr.sbin/ldpd/ldp_peer.c
diff -u src/usr.sbin/ldpd/ldp_peer.c:1.14 src/usr.sbin/ldpd/ldp_peer.c:1.15
--- src/usr.sbin/ldpd/ldp_peer.c:1.14	Thu Jul 18 06:07:45 2013
+++ src/usr.sbin/ldpd/ldp_peer.c	Sat Jul 20 05:16:08 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: ldp_peer.c,v 1.14 2013/07/18 06:07:45 kefren Exp $ */
+/* $NetBSD: ldp_peer.c,v 1.15 2013/07/20 05:16:08 kefren Exp $ */
 
 /*
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -38,6 +38,7 @@
 
 #include <assert.h>
 #include <errno.h>
+#include <fcntl.h>
 #include <stdlib.h>
 #include <strings.h>
 #include <stdio.h>
@@ -77,12 +78,11 @@ ldp_peer_new(const struct in_addr * ldp_
 	     const struct sockaddr * tradd, uint16_t holdtime, int soc)
 {
 	struct ldp_peer *p;
-	int s = soc;
-	struct sockaddr *connecting_sa = NULL;
+	int s = soc, sopts;
+	union sockunion connecting_su;
 	struct conf_neighbour *cn;
 
-	if (tradd != NULL)
-		assert(tradd->sa_family == padd->sa_family);
+	assert(tradd == NULL || tradd->sa_family == padd->sa_family);
 
 	if (soc < 1) {
 		s = socket(PF_INET, SOCK_STREAM, 0);
@@ -91,22 +91,20 @@ ldp_peer_new(const struct in_addr * ldp_
 			return NULL;
 		}
 		if (tradd != NULL) {
-			connecting_sa = malloc(tradd->sa_len);
-			memcpy(connecting_sa, tradd, tradd->sa_len);
+			assert(tradd->sa_len <= sizeof(connecting_su));
+			memcpy(&connecting_su, tradd, tradd->sa_len);
 		} else {
-			connecting_sa = malloc(padd->sa_len);
-			memcpy(connecting_sa, padd, padd->sa_len);
+			assert(padd->sa_len <= sizeof(connecting_su));
+			memcpy(&connecting_su, padd, padd->sa_len);
 		}
 
-		assert(connecting_sa->sa_family == AF_INET ||
-		    connecting_sa->sa_family == AF_INET6);
+		assert(connecting_su.sa.sa_family == AF_INET ||
+		    connecting_su.sa.sa_family == AF_INET6);
 
-		if (connecting_sa->sa_family == AF_INET)
-			((struct sockaddr_in*)connecting_sa)->sin_port =
-			    htons(LDP_PORT);
+		if (connecting_su.sa.sa_family == AF_INET)
+			connecting_su.sin.sin_port = htons(LDP_PORT);
 		else
-			((struct sockaddr_in6*)connecting_sa)->sin6_port =
-			    htons(LDP_PORT);
+			connecting_su.sin6.sin6_port = htons(LDP_PORT);
 
 		set_ttl(s);
 	}
@@ -155,20 +153,23 @@ ldp_peer_new(const struct in_addr * ldp_
 	SLIST_INIT(&p->label_mapping_head);
 	p->timeout = p->holdtime;
 
+	sopts = fcntl(p->socket, F_GETFL);
+	if (sopts >= 0) {
+		sopts |= O_NONBLOCK;
+		fcntl(p->socket, F_SETFL, &sopts);
+	}
+
 	/* And connect to peer */
-	if (soc < 1)
-		if (connect(s, connecting_sa, connecting_sa->sa_len) == -1) {
-			if (errno == EINTR) {
-				free(connecting_sa);
-				return p;	/* We take care of this in
-						 * big_loop */
-			}
-			warnp("connect to %s failed: %s\n",
-			    satos(connecting_sa), strerror(errno));
-			free(connecting_sa);
-			ldp_peer_holddown(p);
-			return NULL;
-		}
+	if (soc < 1 &&
+	    connect(s, &connecting_su.sa, connecting_su.sa.sa_len) == -1) {
+		if (errno == EINTR || errno == EINPROGRESS)
+			/* We take care of this in big_loop */
+			return p;
+		warnp("connect to %s failed: %s\n",
+		    satos(&connecting_su.sa), strerror(errno));
+		ldp_peer_holddown(p);
+		return NULL;
+	}
 	p->state = LDP_PEER_CONNECTED;
 	return p;
 }
@@ -176,12 +177,15 @@ ldp_peer_new(const struct in_addr * ldp_
 void 
 ldp_peer_holddown(struct ldp_peer * p)
 {
-	if (!p)
+
+	if (!p || p->state == LDP_PEER_HOLDDOWN)
 		return;
-	if (p->state == LDP_PEER_ESTABLISHED)
+	if (p->state == LDP_PEER_ESTABLISHED) {
+		p->state = LDP_PEER_HOLDDOWN;
 		mpls_delete_ldp_peer(p);
-	p->state = LDP_PEER_HOLDDOWN;
-	p->timeout = ldp_holddown_time;
+	} else
+		p->state = LDP_PEER_HOLDDOWN;
+	p->timeout = p->holdtime;
 	shutdown(p->socket, SHUT_RDWR);
 	ldp_peer_delete_all_mappings(p);
 	del_all_ifaddr(p);
@@ -457,7 +461,7 @@ ldp_peer_delete_mapping(struct ldp_peer 
 	struct label_mapping *lma;
 
 	if (!a)
-		return ldp_peer_delete_all_mappings(p);
+		return LDP_E_NOENT;
 
 	lma = ldp_peer_get_lm(p, a, prefix);
 	if (!lma)
@@ -486,7 +490,7 @@ ldp_peer_get_lm(const struct ldp_peer * 
 
 }
 
-int
+void
 ldp_peer_delete_all_mappings(struct ldp_peer * p)
 {
 	struct label_mapping *lma;
@@ -496,8 +500,6 @@ ldp_peer_delete_all_mappings(struct ldp_
 		SLIST_REMOVE_HEAD(&p->label_mapping_head, mappings);
 		free(lma);
 	}
-
-	return LDP_E_OK;
 }
 
 /* returns a mapping and its peer */

Index: src/usr.sbin/ldpd/ldp_peer.h
diff -u src/usr.sbin/ldpd/ldp_peer.h:1.6 src/usr.sbin/ldpd/ldp_peer.h:1.7
--- src/usr.sbin/ldpd/ldp_peer.h:1.6	Thu Jul 11 05:55:13 2013
+++ src/usr.sbin/ldpd/ldp_peer.h	Sat Jul 20 05:16:08 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: ldp_peer.h,v 1.6 2013/07/11 05:55:13 kefren Exp $ */
+/* $NetBSD: ldp_peer.h,v 1.7 2013/07/20 05:16:08 kefren Exp $ */
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -108,7 +108,7 @@ int ldp_peer_add_mapping(struct ldp_peer
 int ldp_peer_delete_mapping(struct ldp_peer *, const struct sockaddr *, int);
 struct label_mapping * ldp_peer_get_lm(const struct ldp_peer *,
 	const struct sockaddr *, uint);
-int ldp_peer_delete_all_mappings(struct ldp_peer *);
+void ldp_peer_delete_all_mappings(struct ldp_peer *);
 void ldp_peer_holddown_all(void);
 
 struct peer_map * ldp_test_mapping(const struct sockaddr *, int,

Index: src/usr.sbin/ldpd/mpls_routes.c
diff -u src/usr.sbin/ldpd/mpls_routes.c:1.18 src/usr.sbin/ldpd/mpls_routes.c:1.19
--- src/usr.sbin/ldpd/mpls_routes.c:1.18	Thu Jul 18 11:45:36 2013
+++ src/usr.sbin/ldpd/mpls_routes.c	Sat Jul 20 05:16:08 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: mpls_routes.c,v 1.18 2013/07/18 11:45:36 kefren Exp $ */
+/* $NetBSD: mpls_routes.c,v 1.19 2013/07/20 05:16:08 kefren Exp $ */
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -678,8 +678,6 @@ check_route(struct rt_msg * rg, uint rle
 			      satos(&so_dest->sa), prefixlen);
 		break;
 	case RTM_DELETE:
-		if (!so_gate)
-			break;	/* Non-existent route  XXX ?! */
 		/*
 		 * Send withdraw check the binding, delete the route, delete
 		 * the binding

Index: src/usr.sbin/ldpd/socketops.c
diff -u src/usr.sbin/ldpd/socketops.c:1.29 src/usr.sbin/ldpd/socketops.c:1.30
--- src/usr.sbin/ldpd/socketops.c:1.29	Thu Jul 18 06:07:45 2013
+++ src/usr.sbin/ldpd/socketops.c	Sat Jul 20 05:16:08 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: socketops.c,v 1.29 2013/07/18 06:07:45 kefren Exp $ */
+/* $NetBSD: socketops.c,v 1.30 2013/07/20 05:16:08 kefren Exp $ */
 
 /*
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -932,6 +932,7 @@ the_big_loop(void)
 				p = get_ldp_peer_by_socket(pfd[i].fd);
 				if (!p)
 					continue;
+				assert(p->state == LDP_PEER_CONNECTING);
 				if (getsockopt(pfd[i].fd, SOL_SOCKET, SO_ERROR,
 				    &sock_error, &sock_error_size) != 0 ||
 				    sock_error != 0) {
@@ -1078,7 +1079,9 @@ recv_session_pdu(struct ldp_peer * p)
 
 	memset(recvspace, 0, MAX_PDU_SIZE);
 
-	c = recv(p->socket, (void *) recvspace, MAX_PDU_SIZE, MSG_PEEK);
+	do {
+		c = recv(p->socket, (void *) recvspace, MAX_PDU_SIZE, MSG_PEEK);
+	} while (c == -1 && errno == EINTR);
 
 	debugp("Ready to read %d bytes\n", c);
 
@@ -1097,12 +1100,12 @@ recv_session_pdu(struct ldp_peer * p)
 		return;
 	}
 	rpdu = (struct ldp_pdu *) recvspace;
-	/* XXX: buggy messages may crash the whole thing */
-	c = recv(p->socket, (void *) recvspace,
-		ntohs(rpdu->length) + PDU_VER_LENGTH, MSG_WAITALL);
-	rpdu = (struct ldp_pdu *) recvspace;
+	do {
+		c = recv(p->socket, (void *) recvspace,
+		    ntohs(rpdu->length) + PDU_VER_LENGTH, MSG_WAITALL);
+	} while (c == -1 && errno == EINTR);
 
-	/* Check if it's somehow OK... */
+	/* sanity check */
 	if (check_recv_pdu(p, rpdu, c) != 0)
 		return;
 

Index: src/usr.sbin/ldpd/tlv_stack.c
diff -u src/usr.sbin/ldpd/tlv_stack.c:1.11 src/usr.sbin/ldpd/tlv_stack.c:1.12
--- src/usr.sbin/ldpd/tlv_stack.c:1.11	Thu Jul 18 11:45:36 2013
+++ src/usr.sbin/ldpd/tlv_stack.c	Sat Jul 20 05:16:08 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: tlv_stack.c,v 1.11 2013/07/18 11:45:36 kefren Exp $ */
+/* $NetBSD: tlv_stack.c,v 1.12 2013/07/20 05:16:08 kefren Exp $ */
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -209,7 +209,7 @@ withdraw_label(struct ldp_peer * p, stru
 	    case FEC_WILDCARD:
 		fatalp("LDP neighbour %s: Wildcard withdraw !!!\n",
 		    satos(p->address));
-		ldp_peer_delete_mapping(p, NULL, 0);
+		ldp_peer_delete_all_mappings(p);
 		label_reattach_all_peer_labels(p, REATT_INET_CHANGE);
 		break;
 	    default:
@@ -222,7 +222,7 @@ withdraw_label(struct ldp_peer * p, stru
 
 
 /*
- * In case of label redraw, reuse the same buffer to send label release
+ * In case of label withdraw, reuse the same buffer to send label release
  * Simply replace type and message id
  */
 void 
@@ -322,7 +322,8 @@ send_label_tlv_to_all(const struct socka
 {
 	struct ldp_peer *p;
 	SLIST_FOREACH(p, &ldp_peer_head, peers)
-		send_label_tlv(p, addr, prefixlen, label, NULL);
+		if (p->state == LDP_PEER_ESTABLISHED)
+			send_label_tlv(p, addr, prefixlen, label, NULL);
 }
 
 /*
@@ -400,7 +401,8 @@ send_withdraw_tlv_to_all(const struct so
 {
 	struct ldp_peer *p;
 	SLIST_FOREACH(p, &ldp_peer_head, peers)
-		send_withdraw_tlv(p, addr, prefixlen);
+		if (p->state == LDP_PEER_ESTABLISHED)
+			send_withdraw_tlv(p, addr, prefixlen);
 }
 
 int

Reply via email to