Stop confusing peer hello source with peer transport address
This commit is contained in:
parent
9005bc5cfd
commit
dc76929a7a
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user