mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-24 11:29:10 +00:00
Ignore peer addresses in a consistent way also when checking for
new addresses during restart. If this is not done, restart doesn't work when the local socket is IPv4 only and the peer uses IPv4 and IPv6 addresses. MFC after: 3 days.
This commit is contained in:
parent
4ac8a40011
commit
843d04a89e
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=295069
@ -5307,6 +5307,7 @@ sctp_are_there_new_addresses(struct sctp_association *asoc,
|
||||
uint16_t ptype, plen;
|
||||
uint8_t fnd;
|
||||
struct sctp_nets *net;
|
||||
int check_src;
|
||||
|
||||
#ifdef INET
|
||||
struct sockaddr_in sin4, *sa4;
|
||||
@ -5328,39 +5329,61 @@ sctp_are_there_new_addresses(struct sctp_association *asoc,
|
||||
sin6.sin6_len = sizeof(sin6);
|
||||
#endif
|
||||
/* First what about the src address of the pkt ? */
|
||||
fnd = 0;
|
||||
TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
|
||||
sa = (struct sockaddr *)&net->ro._l_addr;
|
||||
if (sa->sa_family == src->sa_family) {
|
||||
check_src = 0;
|
||||
switch (src->sa_family) {
|
||||
#ifdef INET
|
||||
if (sa->sa_family == AF_INET) {
|
||||
struct sockaddr_in *src4;
|
||||
|
||||
sa4 = (struct sockaddr_in *)sa;
|
||||
src4 = (struct sockaddr_in *)src;
|
||||
if (sa4->sin_addr.s_addr == src4->sin_addr.s_addr) {
|
||||
fnd = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
case AF_INET:
|
||||
if (asoc->scope.ipv4_addr_legal) {
|
||||
check_src = 1;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef INET6
|
||||
if (sa->sa_family == AF_INET6) {
|
||||
struct sockaddr_in6 *src6;
|
||||
|
||||
sa6 = (struct sockaddr_in6 *)sa;
|
||||
src6 = (struct sockaddr_in6 *)src;
|
||||
if (SCTP6_ARE_ADDR_EQUAL(sa6, src6)) {
|
||||
fnd = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
case AF_INET6:
|
||||
if (asoc->scope.ipv6_addr_legal) {
|
||||
check_src = 1;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
/* TSNH */
|
||||
break;
|
||||
}
|
||||
if (fnd == 0) {
|
||||
/* New address added! no need to look futher. */
|
||||
return (1);
|
||||
if (check_src) {
|
||||
fnd = 0;
|
||||
TAILQ_FOREACH(net, &asoc->nets, sctp_next) {
|
||||
sa = (struct sockaddr *)&net->ro._l_addr;
|
||||
if (sa->sa_family == src->sa_family) {
|
||||
#ifdef INET
|
||||
if (sa->sa_family == AF_INET) {
|
||||
struct sockaddr_in *src4;
|
||||
|
||||
sa4 = (struct sockaddr_in *)sa;
|
||||
src4 = (struct sockaddr_in *)src;
|
||||
if (sa4->sin_addr.s_addr == src4->sin_addr.s_addr) {
|
||||
fnd = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef INET6
|
||||
if (sa->sa_family == AF_INET6) {
|
||||
struct sockaddr_in6 *src6;
|
||||
|
||||
sa6 = (struct sockaddr_in6 *)sa;
|
||||
src6 = (struct sockaddr_in6 *)src;
|
||||
if (SCTP6_ARE_ADDR_EQUAL(sa6, src6)) {
|
||||
fnd = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (fnd == 0) {
|
||||
/* New address added! no need to look futher. */
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
/* Ok so far lets munge through the rest of the packet */
|
||||
offset += sizeof(struct sctp_init_chunk);
|
||||
@ -5381,9 +5404,11 @@ sctp_are_there_new_addresses(struct sctp_association *asoc,
|
||||
phdr == NULL) {
|
||||
return (1);
|
||||
}
|
||||
p4 = (struct sctp_ipv4addr_param *)phdr;
|
||||
sin4.sin_addr.s_addr = p4->addr;
|
||||
sa_touse = (struct sockaddr *)&sin4;
|
||||
if (asoc->scope.ipv4_addr_legal) {
|
||||
p4 = (struct sctp_ipv4addr_param *)phdr;
|
||||
sin4.sin_addr.s_addr = p4->addr;
|
||||
sa_touse = (struct sockaddr *)&sin4;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
@ -5398,10 +5423,12 @@ sctp_are_there_new_addresses(struct sctp_association *asoc,
|
||||
phdr == NULL) {
|
||||
return (1);
|
||||
}
|
||||
p6 = (struct sctp_ipv6addr_param *)phdr;
|
||||
memcpy((caddr_t)&sin6.sin6_addr, p6->addr,
|
||||
sizeof(p6->addr));
|
||||
sa_touse = (struct sockaddr *)&sin6;
|
||||
if (asoc->scope.ipv6_addr_legal) {
|
||||
p6 = (struct sctp_ipv6addr_param *)phdr;
|
||||
memcpy((caddr_t)&sin6.sin6_addr, p6->addr,
|
||||
sizeof(p6->addr));
|
||||
sa_touse = (struct sockaddr *)&sin6;
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user