Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.sbin/ldpd don't connect on first hello, there are chance...



details:   https://anonhg.NetBSD.org/src/rev/286bbe1b5437
branches:  trunk
changeset: 788798:286bbe1b5437
user:      kefren <kefren%NetBSD.org@localhost>
date:      Sat Jul 20 05:16:08 2013 +0000

description:
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

diffstat:

 usr.sbin/ldpd/fsm.c         |   4 +-
 usr.sbin/ldpd/ldp_peer.c    |  76 +++++++++++++++++++++++---------------------
 usr.sbin/ldpd/ldp_peer.h    |   4 +-
 usr.sbin/ldpd/mpls_routes.c |   4 +-
 usr.sbin/ldpd/socketops.c   |  17 +++++----
 usr.sbin/ldpd/tlv_stack.c   |  12 ++++--
 6 files changed, 62 insertions(+), 55 deletions(-)

diffs (truncated from 302 to 300 lines):

diff -r f0b2ca2d73db -r 286bbe1b5437 usr.sbin/ldpd/fsm.c
--- a/usr.sbin/ldpd/fsm.c       Sat Jul 20 04:46:58 2013 +0000
+++ b/usr.sbin/ldpd/fsm.c       Sat Jul 20 05:16:08 2013 +0000
@@ -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 @@
                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 @@
        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;
 }
diff -r f0b2ca2d73db -r 286bbe1b5437 usr.sbin/ldpd/ldp_peer.c
--- a/usr.sbin/ldpd/ldp_peer.c  Sat Jul 20 04:46:58 2013 +0000
+++ b/usr.sbin/ldpd/ldp_peer.c  Sat Jul 20 05:16:08 2013 +0000
@@ -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 @@
             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 @@
                        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 @@
        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 @@
 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 @@
        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 @@
 
 }
 
-int
+void
 ldp_peer_delete_all_mappings(struct ldp_peer * p)
 {
        struct label_mapping *lma;
@@ -496,8 +500,6 @@
                SLIST_REMOVE_HEAD(&p->label_mapping_head, mappings);
                free(lma);
        }
-
-       return LDP_E_OK;
 }
 
 /* returns a mapping and its peer */
diff -r f0b2ca2d73db -r 286bbe1b5437 usr.sbin/ldpd/ldp_peer.h
--- a/usr.sbin/ldpd/ldp_peer.h  Sat Jul 20 04:46:58 2013 +0000
+++ b/usr.sbin/ldpd/ldp_peer.h  Sat Jul 20 05:16:08 2013 +0000
@@ -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_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,
diff -r f0b2ca2d73db -r 286bbe1b5437 usr.sbin/ldpd/mpls_routes.c
--- a/usr.sbin/ldpd/mpls_routes.c       Sat Jul 20 04:46:58 2013 +0000
+++ b/usr.sbin/ldpd/mpls_routes.c       Sat Jul 20 05:16:08 2013 +0000
@@ -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 @@
                              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
diff -r f0b2ca2d73db -r 286bbe1b5437 usr.sbin/ldpd/socketops.c
--- a/usr.sbin/ldpd/socketops.c Sat Jul 20 04:46:58 2013 +0000
+++ b/usr.sbin/ldpd/socketops.c Sat Jul 20 05:16:08 2013 +0000
@@ -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 @@
                                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 @@
 
        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 @@
                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;
 
diff -r f0b2ca2d73db -r 286bbe1b5437 usr.sbin/ldpd/tlv_stack.c
--- a/usr.sbin/ldpd/tlv_stack.c Sat Jul 20 04:46:58 2013 +0000
+++ b/usr.sbin/ldpd/tlv_stack.c Sat Jul 20 05:16:08 2013 +0000
@@ -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 @@
            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 @@
 
 
 /*
- * 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 @@
 {
        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 @@
 {
        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);
 }



Home | Main Index | Thread Index | Old Index