Stop confusing peer hello source with peer transport address

This commit is contained in:
kefren 2013-02-05 13:02:33 +00:00
parent 9005bc5cfd
commit dc76929a7a

View File

@ -1,4 +1,4 @@
/* $NetBSD: fsm.c,v 1.9 2013/02/03 19:41:59 kefren Exp $ */
/* $NetBSD: fsm.c,v 1.10 2013/02/05 13:02:33 kefren Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
@ -56,7 +56,8 @@ run_ldp_hello(struct ldp_pdu * pduid, struct hello_tlv * ht,
{
struct ldp_peer *peer = NULL;
struct transport_address_tlv *trtlv;
struct hello_info *hi;
struct hello_info *hi = NULL;
union sockunion traddr;
if ((!pduid) || (!ht))
return;
@ -65,23 +66,6 @@ run_ldp_hello(struct ldp_pdu * pduid, struct hello_tlv * ht,
debugp("Hello: Type: 0x%.4X Length: %.2d ID: %.8X\n", ht->type,
ht->length, ht->messageid);
/* Add it to hello list or just update timer */
SLIST_FOREACH(hi, &hello_info_head, infos)
if (hi->ldp_id.s_addr == pduid->ldp_id.s_addr)
break;
if (hi == NULL) {
hi = malloc(sizeof(*hi));
if (!hi) {
fatalp("Cannot alloc a hello info structure");
return;
}
hi->ldp_id.s_addr = pduid->ldp_id.s_addr;
hi->transport_address.sa.sa_family = 0;
SLIST_INSERT_HEAD(&hello_info_head, hi, infos);
} else
/* Just update timer */
hi->keepalive = LDP_HELLO_KEEP;
if (ht->length <= 4) /* Common hello parameters */
return;
ht->ch.type = ntohs(ht->ch.type);
@ -91,6 +75,49 @@ run_ldp_hello(struct ldp_pdu * pduid, struct hello_tlv * ht,
debugp("Common hello Type: 0x%.4X Length: %.2d R:%d T:%d"
" Hold time: %d\n", ht->ch.type, ht->ch.length,
ht->ch.tr / 2, ht->ch.tr % 2, ht->ch.holdtime);
memset(&traddr, 0, sizeof(traddr));
/* Check transport TLV */
if (pduid->length - PDU_PAYLOAD_LENGTH -
sizeof(struct hello_tlv) >= 8) {
trtlv = (struct transport_address_tlv *)(ht + 1);
if (trtlv->type == htons(TLV_IPV4_TRANSPORT)) {
traddr.sin.sin_family = AF_INET;
traddr.sin.sin_len = sizeof(struct sockaddr_in);
memcpy(&traddr.sin.sin_addr,
&trtlv->address, sizeof(struct in_addr));
} else if (trtlv->type == htons(TLV_IPV6_TRANSPORT)) {
traddr.sin6.sin6_family = AF_INET6;
traddr.sin6.sin6_len = sizeof(struct sockaddr_in6);
memcpy(&traddr.sin6.sin6_addr,
&trtlv->address, sizeof(struct in6_addr));
} else
warnp("Unknown AF %x for transport address\n",
ntohs(trtlv->type));
} else {
/* Use LDP ID as transport address */
traddr.sin.sin_family = AF_INET;
traddr.sin.sin_len = sizeof(struct sockaddr_in);
memcpy(&traddr.sin.sin_addr,
&pduid->ldp_id, sizeof(struct in_addr));
}
/* Add it to hello list or just update timer */
SLIST_FOREACH(hi, &hello_info_head, infos)
if (hi->ldp_id.s_addr == pduid->ldp_id.s_addr &&
sockaddr_cmp(&hi->transport_address.sa, &traddr.sa) == 0)
break;
if (hi == NULL) {
hi = calloc(1, sizeof(*hi));
if (!hi) {
fatalp("Cannot alloc a hello info structure");
return;
}
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);
}
/* Update expire timer */
if (ht->ch.holdtime != 0)
hi->keepalive = ht->ch.holdtime;
else {
@ -99,44 +126,16 @@ run_ldp_hello(struct ldp_pdu * pduid, struct hello_tlv * ht,
else
hi->keepalive = LDP_THELLO_KEEP;
}
if (!get_ldp_peer_by_id(&pduid->ldp_id)) {
/* Check transport TLV */
if (pduid->length - PDU_PAYLOAD_LENGTH -
sizeof(struct hello_tlv) >= 8) {
trtlv = (struct transport_address_tlv *)(ht + 1);
if (trtlv->type == htons(TLV_IPV4_TRANSPORT)) {
hi->transport_address.sin.sin_family = AF_INET;
hi->transport_address.sin.sin_len =
sizeof(struct sockaddr_in);
memcpy(&hi->transport_address.sin.sin_addr,
&trtlv->address, sizeof(struct in_addr));
} else if (trtlv->type == htons(TLV_IPV6_TRANSPORT)) {
hi->transport_address.sin6.sin6_family =
AF_INET6;
hi->transport_address.sin6.sin6_len =
sizeof(struct sockaddr_in6);
memcpy(&hi->transport_address.sin6.sin6_addr,
&trtlv->address, sizeof(struct in6_addr));
} else
warnp("Unknown AF %x for transport address\n",
ntohs(trtlv->type));
} else {
trtlv = NULL;
hi->transport_address.sin.sin_family = AF_INET;
hi->transport_address.sin.sin_len =
sizeof(struct sockaddr_in);
memcpy(&hi->transport_address.sin.sin_addr,
&pduid->ldp_id, sizeof(struct in_addr));
}
/*
* RFC 5036 2.5.2: If A1 > A2, LSR1 plays the active role;
* otherwise it is passive.
*/
/* XXX TODO: check for IPv6 too */
if (may_connect == true &&
hi->transport_address.sa.sa_family == AF_INET &&
(hi->transport_address.sa.sa_family == AF_INET &&
ntohl(hi->transport_address.sin.sin_addr.s_addr) <
ntohl(ladd->s_addr)) {
ntohl(ladd->s_addr))) {
peer = ldp_peer_new(&pduid->ldp_id, padd,
&hi->transport_address.sa,
ht->ch.holdtime, 0);