Module Name: src Committed By: kefren Date: Mon Feb 4 17:14:32 UTC 2013
Modified Files: src/usr.sbin/ldpd: ldp_peer.c ldp_peer.h pdu.c socketops.c Log Message: * Don't assume INET in connection path * Lookup in hello list in order to get the correct LDP ID, instead of transport address * Improve an error message To generate a diff of this commit: cvs rdiff -u -r1.9 -r1.10 src/usr.sbin/ldpd/ldp_peer.c cvs rdiff -u -r1.3 -r1.4 src/usr.sbin/ldpd/ldp_peer.h src/usr.sbin/ldpd/pdu.c cvs rdiff -u -r1.24 -r1.25 src/usr.sbin/ldpd/socketops.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/ldp_peer.c diff -u src/usr.sbin/ldpd/ldp_peer.c:1.9 src/usr.sbin/ldpd/ldp_peer.c:1.10 --- src/usr.sbin/ldpd/ldp_peer.c:1.9 Mon Feb 4 09:52:43 2013 +++ src/usr.sbin/ldpd/ldp_peer.c Mon Feb 4 17:14:31 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: ldp_peer.c,v 1.9 2013/02/04 09:52:43 kefren Exp $ */ +/* $NetBSD: ldp_peer.c,v 1.10 2013/02/04 17:14:31 kefren Exp $ */ /* * Copyright (c) 2010 The NetBSD Foundation, Inc. @@ -63,7 +63,7 @@ ldp_peer_init(void) myaddresses = NULL; } -static int +int sockaddr_cmp(const struct sockaddr *a, const struct sockaddr *b) { if (a->sa_len != b->sa_len || a->sa_family != b->sa_family) Index: src/usr.sbin/ldpd/ldp_peer.h diff -u src/usr.sbin/ldpd/ldp_peer.h:1.3 src/usr.sbin/ldpd/ldp_peer.h:1.4 --- src/usr.sbin/ldpd/ldp_peer.h:1.3 Sat Jan 26 17:29:55 2013 +++ src/usr.sbin/ldpd/ldp_peer.h Mon Feb 4 17:14:31 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: ldp_peer.h,v 1.3 2013/01/26 17:29:55 kefren Exp $ */ +/* $NetBSD: ldp_peer.h,v 1.4 2013/02/04 17:14:31 kefren Exp $ */ /*- * Copyright (c) 2010 The NetBSD Foundation, Inc. @@ -86,6 +86,7 @@ struct peer_map { #define LDP_PEER_ESTABLISHED 2 #define LDP_PEER_HOLDDOWN 3 +int sockaddr_cmp(const struct sockaddr *, const struct sockaddr *); void ldp_peer_init(void); struct ldp_peer * ldp_peer_new(const struct in_addr *, struct sockaddr *, struct sockaddr *, uint16_t, int); Index: src/usr.sbin/ldpd/pdu.c diff -u src/usr.sbin/ldpd/pdu.c:1.3 src/usr.sbin/ldpd/pdu.c:1.4 --- src/usr.sbin/ldpd/pdu.c:1.3 Mon Jan 28 21:35:35 2013 +++ src/usr.sbin/ldpd/pdu.c Mon Feb 4 17:14:31 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: pdu.c,v 1.3 2013/01/28 21:35:35 kefren Exp $ */ +/* $NetBSD: pdu.c,v 1.4 2013/02/04 17:14:31 kefren Exp $ */ /*- * Copyright (c) 2010 The NetBSD Foundation, Inc. @@ -67,8 +67,9 @@ check_recv_pdu(struct ldp_peer * p, stru return LDP_E_BAD_LENGTH; if (p->ldp_id.s_addr != rpdu->ldp_id.s_addr) { - fatalp("Invalid LDP ID received from %s\n", - inet_ntoa(p->ldp_id)); + fatalp("Invalid LDP ID %s received from ", + inet_ntoa(rpdu->ldp_id)); + fatalp("%s\n", inet_ntoa(p->ldp_id)); notiftlv = build_notification(0, NOTIF_FATAL | NOTIF_BAD_LDP_ID); send_tlv(p, (struct tlv *) notiftlv); Index: src/usr.sbin/ldpd/socketops.c diff -u src/usr.sbin/ldpd/socketops.c:1.24 src/usr.sbin/ldpd/socketops.c:1.25 --- src/usr.sbin/ldpd/socketops.c:1.24 Sun Feb 3 19:41:59 2013 +++ src/usr.sbin/ldpd/socketops.c Mon Feb 4 17:14:31 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: socketops.c,v 1.24 2013/02/03 19:41:59 kefren Exp $ */ +/* $NetBSD: socketops.c,v 1.25 2013/02/04 17:14:31 kefren Exp $ */ /* * Copyright (c) 2010 The NetBSD Foundation, Inc. @@ -941,38 +941,67 @@ the_big_loop(void) void new_peer_connection() { - struct sockaddr_in sa, sin_me; + union sockunion peer_address, my_address; + struct in_addr *peer_ldp_id = NULL; + struct hello_info *hi; int s; - s = accept(ls, (struct sockaddr *) & sa, - & (socklen_t) { sizeof(struct sockaddr_in) } ); + s = accept(ls, &peer_address.sa, + & (socklen_t) { sizeof(union sockunion) } ); if (s < 0) { fatalp("accept: %s", strerror(errno)); return; } - if (get_ldp_peer((const struct sockaddr *)&sa) != NULL) { + if (get_ldp_peer(&peer_address.sa) != NULL) { close(s); return; } - warnp("Accepted a connection from %s\n", inet_ntoa(sa.sin_addr)); + warnp("Accepted a connection from %s\n", satos(&peer_address.sa)); - if (getsockname(s, (struct sockaddr *)&sin_me, - & (socklen_t) { sizeof(struct sockaddr_in) } )) { + if (getsockname(s, &my_address.sa, + & (socklen_t) { sizeof(union sockunion) } )) { fatalp("new_peer_connection(): cannot getsockname\n"); close(s); return; } + if (peer_address.sa.sa_family == AF_INET) + peer_address.sin.sin_port = 0; + else if (peer_address.sa.sa_family == AF_INET6) + peer_address.sin6.sin6_port = 0; + else { + fatalp("Unknown peer address family\n"); + close(s); + return; + } - if (ntohl(sa.sin_addr.s_addr) < ntohl(sin_me.sin_addr.s_addr)) { + /* Verify if it should connect - XXX: no check for INET6 */ + if (peer_address.sa.sa_family == AF_INET && + ntohl(peer_address.sin.sin_addr.s_addr) < + ntohl(my_address.sin.sin_addr.s_addr)) { fatalp("Peer %s: connect from lower ID\n", - inet_ntoa(sa.sin_addr)); + satos(&peer_address.sa)); close(s); return; } - /* XXX: sa.sin_addr is not peer LDP ID ... */ - ldp_peer_new(&sa.sin_addr, (struct sockaddr *)&sa, NULL, ldp_holddown_time, s); + + /* Match hello info in order to get ldp_id */ + SLIST_FOREACH(hi, &hello_info_head, infos) { + if (sockaddr_cmp(&peer_address.sa, + &hi->transport_address.sa) == 0) { + peer_ldp_id = &hi->ldp_id; + break; + } + } + if (peer_ldp_id == NULL) { + fatalp("Got connection from %s, but no hello info exists\n", + satos(&peer_address.sa)); + close(s); + return; + } else + ldp_peer_new(peer_ldp_id, &peer_address.sa, NULL, + ldp_holddown_time, s); }