1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <sys/types.h> 30 #include <sys/systm.h> 31 #include <sys/stream.h> 32 #include <sys/cmn_err.h> 33 #include <sys/strsubr.h> 34 35 #include <netinet/in.h> 36 #include <netinet/ip6.h> 37 38 #include <inet/common.h> 39 #include <inet/ip.h> 40 #include <inet/mib2.h> 41 #include "sctp_impl.h" 42 43 void 44 sctp_return_heartbeat(sctp_t *sctp, sctp_chunk_hdr_t *hbcp, mblk_t *mp) 45 { 46 mblk_t *smp; 47 sctp_chunk_hdr_t *cp; 48 ipha_t *iniph; 49 ip6_t *inip6h; 50 int isv4; 51 in6_addr_t addr; 52 sctp_faddr_t *fp; 53 uint16_t len; 54 55 BUMP_LOCAL(sctp->sctp_ibchunks); 56 57 /* Update the faddr for the src addr */ 58 isv4 = (IPH_HDR_VERSION(mp->b_rptr) == IPV4_VERSION); 59 if (isv4) { 60 iniph = (ipha_t *)mp->b_rptr; 61 IN6_IPADDR_TO_V4MAPPED(iniph->ipha_src, &addr); 62 } else { 63 inip6h = (ip6_t *)mp->b_rptr; 64 addr = inip6h->ip6_src; 65 } 66 fp = sctp_lookup_faddr(sctp, &addr); 67 ASSERT(fp != NULL); 68 69 dprint(3, ("sctp_return_heartbeat: %p got hb from %x:%x:%x:%x\n", 70 sctp, SCTP_PRINTADDR(addr))); 71 72 /* 73 * XXX It's really tempting to reuse the heartbeat mblk. But 74 * this complicates processing in sctp_dispatch (i.e. it will 75 * screw up sctp_next_chunk since we will set the chunk 76 * header's length into network byte-order), and if we ever 77 * encounter a heartbeat bundled with other chunks... 78 * So we take the slower-but-safe route. 79 */ 80 len = ntohs(hbcp->sch_len); 81 82 /* Create an IP header, returning to the src addr from the heartbt */ 83 smp = sctp_make_mp(sctp, fp, len); 84 if (smp == NULL) { 85 return; 86 } 87 88 cp = (sctp_chunk_hdr_t *)smp->b_wptr; 89 cp->sch_id = CHUNK_HEARTBEAT_ACK; 90 cp->sch_flags = 0; 91 cp->sch_len = htons(len); 92 93 /* Copy the information field from the heartbeat */ 94 bcopy((void *)(hbcp + 1), (void *)(cp + 1), len - sizeof (*cp)); 95 96 smp->b_wptr += len; 97 98 sctp_set_iplen(sctp, smp); 99 100 BUMP_LOCAL(sctp->sctp_obchunks); 101 sctp_add_sendq(sctp, smp); 102 } 103 104 /* 105 * The data section of the heartbeat contains a time field (lbolt64), 106 * a 64 bit secret, followed by the v6 (possible a v4mapped) address this 107 * heartbeat was sent to. No byte-ordering is done, since the heartbeat 108 * is not interpreted by the peer. 109 */ 110 void 111 sctp_send_heartbeat(sctp_t *sctp, sctp_faddr_t *fp) 112 { 113 sctp_chunk_hdr_t *cp; 114 sctp_parm_hdr_t *hpp; 115 int64_t *t; 116 int64_t now; 117 in6_addr_t *a; 118 mblk_t *hbmp; 119 size_t hblen; 120 121 dprint(3, ("sctp_send_heartbeat: to %x:%x:%x:%x from %x:%x:%x:%x\n", 122 SCTP_PRINTADDR(fp->faddr), SCTP_PRINTADDR(fp->saddr))); 123 124 hblen = sizeof (*cp) + 125 sizeof (*hpp) + 126 sizeof (*t) + 127 sizeof (fp->hb_secret) + 128 sizeof (fp->faddr); 129 hbmp = sctp_make_mp(sctp, fp, hblen); 130 if (hbmp == NULL) 131 return; 132 133 cp = (sctp_chunk_hdr_t *)hbmp->b_wptr; 134 cp->sch_id = CHUNK_HEARTBEAT; 135 cp->sch_flags = 0; 136 cp->sch_len = hblen; 137 cp->sch_len = htons(cp->sch_len); 138 139 hpp = (sctp_parm_hdr_t *)(cp + 1); 140 hpp->sph_type = htons(PARM_HBINFO); 141 hpp->sph_len = hblen - sizeof (*cp); 142 hpp->sph_len = htons(hpp->sph_len); 143 144 /* 145 * Timestamp 146 * 147 * Copy the current time to the heartbeat and we can use it to 148 * calculate the RTT when we get it back in the heartbeat ACK. 149 */ 150 now = lbolt64; 151 t = (int64_t *)(hpp + 1); 152 bcopy(&now, t, sizeof (now)); 153 154 /* 155 * Secret 156 * 157 * The per peer address secret is used to make sure that the heartbeat 158 * ack is really in response to our heartbeat. This prevents blind 159 * spoofing of heartbeat ack to fake the validity of an address. 160 */ 161 t++; 162 bcopy(&fp->hb_secret, t, sizeof (uint64_t)); 163 164 /* 165 * Peer address 166 * 167 * The peer address is used to associate the heartbeat ack with 168 * the correct peer address. The reason is that the peer is 169 * multihomed so that it may not use the same address as source 170 * in response to our heartbeat. 171 */ 172 a = (in6_addr_t *)(t + 1); 173 bcopy(&fp->faddr, a, sizeof (*a)); 174 175 hbmp->b_wptr += hblen; 176 177 sctp_set_iplen(sctp, hbmp); 178 179 /* Update the faddr's info */ 180 fp->lastactive = now; 181 fp->hb_pending = B_TRUE; 182 183 BUMP_LOCAL(sctp->sctp_obchunks); 184 BUMP_MIB(&sctp_mib, sctpTimHeartBeatProbe); 185 186 sctp_add_sendq(sctp, hbmp); 187 } 188 189 /* 190 * Call right after any address change to validate peer addresses. 191 */ 192 void 193 sctp_validate_peer(sctp_t *sctp) 194 { 195 sctp_faddr_t *fp; 196 int cnt; 197 int64_t now; 198 int64_t earliest_expiry; 199 200 now = lbolt64; 201 earliest_expiry = 0; 202 cnt = sctp_maxburst; 203 204 /* 205 * Loop thru the list looking for unconfirmed addresses and 206 * send a heartbeat. But we should only send at most sctp_maxburst 207 * heartbeats. 208 */ 209 for (fp = sctp->sctp_faddrs; fp != NULL; fp = fp->next) { 210 /* No need to validate unreachable address. */ 211 if (fp->state == SCTP_FADDRS_UNREACH) 212 continue; 213 if (fp->state == SCTP_FADDRS_UNCONFIRMED) { 214 if (cnt-- > 0) { 215 fp->hb_expiry = now + fp->rto; 216 sctp_send_heartbeat(sctp, fp); 217 } else { 218 /* 219 * If we cannot send now, be more aggressive 220 * and try again about half of RTO. Note that 221 * all the unsent probes are set to expire at 222 * the same time. 223 */ 224 fp->hb_expiry = now + 225 (sctp->sctp_rto_initial >> 1); 226 } 227 } 228 /* Find the earliest heartbeat expiry time for ALL fps. */ 229 if (fp->hb_interval != 0 && (earliest_expiry == 0 || 230 fp->hb_expiry < earliest_expiry)) { 231 earliest_expiry = fp->hb_expiry; 232 } 233 } 234 /* We use heartbeat timer for autoclose. */ 235 if (sctp->sctp_autoclose != 0) { 236 int64_t expire; 237 238 expire = sctp->sctp_active + sctp->sctp_autoclose; 239 if (earliest_expiry == 0 || expire < earliest_expiry) 240 earliest_expiry = expire; 241 } 242 243 /* 244 * Set the timer to fire for the earliest heartbeat unless 245 * heartbeat is disabled for all addresses. 246 */ 247 if (earliest_expiry != 0) { 248 earliest_expiry -= now; 249 if (earliest_expiry < 0) 250 earliest_expiry = 1; 251 sctp_timer(sctp, sctp->sctp_heartbeat_mp, earliest_expiry); 252 } 253 } 254 255 /* 256 * Process an incoming heartbeat ack. When sending a heartbeat, we 257 * put the timestamp, a secret and the peer address the heartbeat is 258 * sent in the data part of the heartbeat. We will extract this info 259 * and verify that this heartbeat ack is valid. 260 */ 261 void 262 sctp_process_heartbeat(sctp_t *sctp, sctp_chunk_hdr_t *cp) 263 { 264 int64_t *sentp, sent; 265 uint64_t secret; 266 in6_addr_t addr; 267 sctp_faddr_t *fp; 268 sctp_parm_hdr_t *hpp; 269 int64_t now; 270 271 BUMP_LOCAL(sctp->sctp_ibchunks); 272 273 /* Sanity checks */ 274 ASSERT(OK_32PTR(cp)); 275 if (ntohs(cp->sch_len) < (sizeof (*cp) + sizeof (*hpp) + 276 sizeof (sent) + sizeof (secret) + sizeof (addr))) { 277 /* drop it */ 278 dprint(2, ("sctp_process_heartbeat: malformed ack %p\n", 279 sctp)); 280 return; 281 } 282 283 hpp = (sctp_parm_hdr_t *)(cp + 1); 284 if (ntohs(hpp->sph_type) != PARM_HBINFO || 285 ntohs(hpp->sph_len) != (ntohs(cp->sch_len) - sizeof (*cp))) { 286 dprint(2, 287 ("sctp_process_heartbeat: malformed param in ack %p\n", 288 sctp)); 289 return; 290 } 291 292 /* 293 * Pull out the time sent from the ack. 294 * SCTP is 32-bit aligned, so copy 64 bit quantity. Since we 295 * put it in, it should be in our byte order. 296 */ 297 sentp = (int64_t *)(hpp + 1); 298 bcopy(sentp, &sent, sizeof (sent)); 299 300 /* Grab the secret to make sure that this heartbeat is valid */ 301 bcopy(++sentp, &secret, sizeof (secret)); 302 303 /* Next, verify the address to make sure that it is the right one. */ 304 bcopy(++sentp, &addr, sizeof (addr)); 305 fp = sctp_lookup_faddr(sctp, &addr); 306 if (fp == NULL) { 307 dprint(2, ("sctp_process_heartbeat: invalid faddr (sctp=%p)\n", 308 sctp)); 309 return; 310 } 311 if (secret != fp->hb_secret) { 312 dprint(2, 313 ("sctp_process_heartbeat: invalid secret in ack %p\n", 314 sctp)); 315 return; 316 } 317 318 /* This address is now confirmed and alive. */ 319 sctp_faddr_alive(sctp, fp); 320 now = lbolt64; 321 sctp_update_rtt(sctp, fp, now - sent); 322 323 /* 324 * Note that the heartbeat timer should still be running, we don't 325 * reset it to avoid going through the whole list of peer addresses 326 * for each heartbeat ack as we probably are in interrupt context. 327 */ 328 fp->hb_expiry = now + SET_HB_INTVL(fp); 329 } 330