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