/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
#include <inet/ipclassifier.h>
#include "sctp_impl.h"
void
{
int isv4;
/* Update the faddr for the src addr */
if (isv4) {
} else {
}
/* If the source address is bogus we silently drop the packet */
dprint(1,
("sctp_return_heartbeat: %p bogus hb from %x:%x:%x:%x\n",
return;
}
/*
* XXX It's really tempting to reuse the heartbeat mblk. But
* this complicates processing in sctp_dispatch (i.e. it will
* screw up sctp_next_chunk since we will set the chunk
* header's length into network byte-order), and if we ever
* encounter a heartbeat bundled with other chunks...
* So we take the slower-but-safe route.
*/
/* Create an IP header, returning to the src addr from the heartbt */
return;
}
/* Copy the information field from the heartbeat */
}
/*
* The data section of the heartbeat contains a time field (lbolt64),
* a 64 bit secret, followed by the v6 (possible a v4mapped) address this
* heartbeat was sent to. No byte-ordering is done, since the heartbeat
* is not interpreted by the peer.
*/
void
{
int64_t *t;
in6_addr_t *a;
sizeof (*hpp) +
sizeof (*t) +
sizeof (fp->sf_hb_secret) +
return;
}
/*
* Timestamp
*
* Copy the current time to the heartbeat and we can use it to
* calculate the RTT when we get it back in the heartbeat ACK.
*/
now = ddi_get_lbolt64();
/*
* Secret
*
* The per peer address secret is used to make sure that the heartbeat
* ack is really in response to our heartbeat. This prevents blind
* spoofing of heartbeat ack to fake the validity of an address.
*/
t++;
/*
* Peer address
*
* The peer address is used to associate the heartbeat ack with
* the correct peer address. The reason is that the peer is
* multihomed so that it may not use the same address as source
* in response to our heartbeat.
*/
a = (in6_addr_t *)(t + 1);
/* Update the faddr's info */
}
/*
* Call right after any address change to validate peer addresses.
*/
void
{
int cnt;
now = ddi_get_lbolt64();
earliest_expiry = 0;
/*
* Loop thru the list looking for unconfirmed addresses and
* send a heartbeat. But we should only send at most sctp_maxburst
* heartbeats.
*/
/* No need to validate unreachable address. */
continue;
if (cnt-- > 0) {
} else {
/*
* If we cannot send now, be more aggressive
* and try again about half of RTO. Note that
* all the unsent probes are set to expire at
* the same time.
*/
}
}
/* Find the earliest heartbeat expiry time for ALL fps. */
}
}
/* We use heartbeat timer for autoclose. */
if (sctp->sctp_autoclose != 0) {
}
/*
* Set the timer to fire for the earliest heartbeat unless
* heartbeat is disabled for all addresses.
*/
if (earliest_expiry != 0) {
earliest_expiry -= now;
if (earliest_expiry < 0)
earliest_expiry = 1;
}
}
/*
* Process an incoming heartbeat ack. When sending a heartbeat, we
* put the timestamp, a secret and the peer address the heartbeat is
* sent in the data part of the heartbeat. We will extract this info
* and verify that this heartbeat ack is valid.
*/
void
{
/* Sanity checks */
/* drop it */
(void *)sctp));
return;
}
dprint(2,
("sctp_process_heartbeat: malformed param in ack %p\n",
(void *)sctp));
return;
}
/*
* Pull out the time sent from the ack.
* SCTP is 32-bit aligned, so copy 64 bit quantity. Since we
* put it in, it should be in our byte order.
*/
/* Grab the secret to make sure that this heartbeat is valid */
/* Next, verify the address to make sure that it is the right one. */
(void *)sctp));
return;
}
dprint(2,
("sctp_process_heartbeat: invalid secret in ack %p\n",
(void *)sctp));
return;
}
/* This address is now confirmed and alive. */
now = ddi_get_lbolt64();
/*
* Note that the heartbeat timer should still be running, we don't
* reset it to avoid going through the whole list of peer addresses
* for each heartbeat ack as we probably are in interrupt context.
*/
}