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 2006 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 (void *)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 SCTP_KSTAT(sctp_return_hb_failed); 86 return; 87 } 88 89 cp = (sctp_chunk_hdr_t *)smp->b_wptr; 90 cp->sch_id = CHUNK_HEARTBEAT_ACK; 91 cp->sch_flags = 0; 92 cp->sch_len = htons(len); 93 94 /* Copy the information field from the heartbeat */ 95 bcopy((void *)(hbcp + 1), (void *)(cp + 1), len - sizeof (*cp)); 96 97 smp->b_wptr += len; 98 99 sctp_set_iplen(sctp, smp); 100 101 BUMP_LOCAL(sctp->sctp_obchunks); 102 sctp_add_sendq(sctp, smp); 103 } 104 105 /* 106 * The data section of the heartbeat contains a time field (lbolt64), 107 * a 64 bit secret, followed by the v6 (possible a v4mapped) address this 108 * heartbeat was sent to. No byte-ordering is done, since the heartbeat 109 * is not interpreted by the peer. 110 */ 111 void 112 sctp_send_heartbeat(sctp_t *sctp, sctp_faddr_t *fp) 113 { 114 sctp_chunk_hdr_t *cp; 115 sctp_parm_hdr_t *hpp; 116 int64_t *t; 117 int64_t now; 118 in6_addr_t *a; 119 mblk_t *hbmp; 120 size_t hblen; 121 122 dprint(3, ("sctp_send_heartbeat: to %x:%x:%x:%x from %x:%x:%x:%x\n", 123 SCTP_PRINTADDR(fp->faddr), SCTP_PRINTADDR(fp->saddr))); 124 125 hblen = sizeof (*cp) + 126 sizeof (*hpp) + 127 sizeof (*t) + 128 sizeof (fp->hb_secret) + 129 sizeof (fp->faddr); 130 hbmp = sctp_make_mp(sctp, fp, hblen); 131 if (hbmp == NULL) { 132 SCTP_KSTAT(sctp_send_hb_failed); 133 return; 134 } 135 136 cp = (sctp_chunk_hdr_t *)hbmp->b_wptr; 137 cp->sch_id = CHUNK_HEARTBEAT; 138 cp->sch_flags = 0; 139 cp->sch_len = hblen; 140 cp->sch_len = htons(cp->sch_len); 141 142 hpp = (sctp_parm_hdr_t *)(cp + 1); 143 hpp->sph_type = htons(PARM_HBINFO); 144 hpp->sph_len = hblen - sizeof (*cp); 145 hpp->sph_len = htons(hpp->sph_len); 146 147 /* 148 * Timestamp 149 * 150 * Copy the current time to the heartbeat and we can use it to 151 * calculate the RTT when we get it back in the heartbeat ACK. 152 */ 153 now = lbolt64; 154 t = (int64_t *)(hpp + 1); 155 bcopy(&now, t, sizeof (now)); 156 157 /* 158 * Secret 159 * 160 * The per peer address secret is used to make sure that the heartbeat 161 * ack is really in response to our heartbeat. This prevents blind 162 * spoofing of heartbeat ack to fake the validity of an address. 163 */ 164 t++; 165 bcopy(&fp->hb_secret, t, sizeof (uint64_t)); 166 167 /* 168 * Peer address 169 * 170 * The peer address is used to associate the heartbeat ack with 171 * the correct peer address. The reason is that the peer is 172 * multihomed so that it may not use the same address as source 173 * in response to our heartbeat. 174 */ 175 a = (in6_addr_t *)(t + 1); 176 bcopy(&fp->faddr, a, sizeof (*a)); 177 178 hbmp->b_wptr += hblen; 179 180 sctp_set_iplen(sctp, hbmp); 181 182 /* Update the faddr's info */ 183 fp->lastactive = now; 184 fp->hb_pending = B_TRUE; 185 186 BUMP_LOCAL(sctp->sctp_obchunks); 187 BUMP_MIB(&sctp_mib, sctpTimHeartBeatProbe); 188 189 sctp_add_sendq(sctp, hbmp); 190 } 191 192 /* 193 * Call right after any address change to validate peer addresses. 194 */ 195 void 196 sctp_validate_peer(sctp_t *sctp) 197 { 198 sctp_faddr_t *fp; 199 int cnt; 200 int64_t now; 201 int64_t earliest_expiry; 202 203 now = lbolt64; 204 earliest_expiry = 0; 205 cnt = sctp_maxburst; 206 207 /* 208 * Loop thru the list looking for unconfirmed addresses and 209 * send a heartbeat. But we should only send at most sctp_maxburst 210 * heartbeats. 211 */ 212 for (fp = sctp->sctp_faddrs; fp != NULL; fp = fp->next) { 213 /* No need to validate unreachable address. */ 214 if (fp->state == SCTP_FADDRS_UNREACH) 215 continue; 216 if (fp->state == SCTP_FADDRS_UNCONFIRMED) { 217 if (cnt-- > 0) { 218 fp->hb_expiry = now + fp->rto; 219 sctp_send_heartbeat(sctp, fp); 220 } else { 221 /* 222 * If we cannot send now, be more aggressive 223 * and try again about half of RTO. Note that 224 * all the unsent probes are set to expire at 225 * the same time. 226 */ 227 fp->hb_expiry = now + 228 (sctp->sctp_rto_initial >> 1); 229 } 230 } 231 /* Find the earliest heartbeat expiry time for ALL fps. */ 232 if (fp->hb_interval != 0 && (earliest_expiry == 0 || 233 fp->hb_expiry < earliest_expiry)) { 234 earliest_expiry = fp->hb_expiry; 235 } 236 } 237 /* We use heartbeat timer for autoclose. */ 238 if (sctp->sctp_autoclose != 0) { 239 int64_t expire; 240 241 expire = sctp->sctp_active + sctp->sctp_autoclose; 242 if (earliest_expiry == 0 || expire < earliest_expiry) 243 earliest_expiry = expire; 244 } 245 246 /* 247 * Set the timer to fire for the earliest heartbeat unless 248 * heartbeat is disabled for all addresses. 249 */ 250 if (earliest_expiry != 0) { 251 earliest_expiry -= now; 252 if (earliest_expiry < 0) 253 earliest_expiry = 1; 254 sctp_timer(sctp, sctp->sctp_heartbeat_mp, earliest_expiry); 255 } 256 } 257 258 /* 259 * Process an incoming heartbeat ack. When sending a heartbeat, we 260 * put the timestamp, a secret and the peer address the heartbeat is 261 * sent in the data part of the heartbeat. We will extract this info 262 * and verify that this heartbeat ack is valid. 263 */ 264 void 265 sctp_process_heartbeat(sctp_t *sctp, sctp_chunk_hdr_t *cp) 266 { 267 int64_t *sentp, sent; 268 uint64_t secret; 269 in6_addr_t addr; 270 sctp_faddr_t *fp; 271 sctp_parm_hdr_t *hpp; 272 int64_t now; 273 274 BUMP_LOCAL(sctp->sctp_ibchunks); 275 276 /* Sanity checks */ 277 ASSERT(OK_32PTR(cp)); 278 if (ntohs(cp->sch_len) < (sizeof (*cp) + sizeof (*hpp) + 279 sizeof (sent) + sizeof (secret) + sizeof (addr))) { 280 /* drop it */ 281 dprint(2, ("sctp_process_heartbeat: malformed ack %p\n", 282 (void *)sctp)); 283 return; 284 } 285 286 hpp = (sctp_parm_hdr_t *)(cp + 1); 287 if (ntohs(hpp->sph_type) != PARM_HBINFO || 288 ntohs(hpp->sph_len) != (ntohs(cp->sch_len) - sizeof (*cp))) { 289 dprint(2, 290 ("sctp_process_heartbeat: malformed param in ack %p\n", 291 (void *)sctp)); 292 return; 293 } 294 295 /* 296 * Pull out the time sent from the ack. 297 * SCTP is 32-bit aligned, so copy 64 bit quantity. Since we 298 * put it in, it should be in our byte order. 299 */ 300 sentp = (int64_t *)(hpp + 1); 301 bcopy(sentp, &sent, sizeof (sent)); 302 303 /* Grab the secret to make sure that this heartbeat is valid */ 304 bcopy(++sentp, &secret, sizeof (secret)); 305 306 /* Next, verify the address to make sure that it is the right one. */ 307 bcopy(++sentp, &addr, sizeof (addr)); 308 fp = sctp_lookup_faddr(sctp, &addr); 309 if (fp == NULL) { 310 dprint(2, ("sctp_process_heartbeat: invalid faddr (sctp=%p)\n", 311 (void *)sctp)); 312 return; 313 } 314 if (secret != fp->hb_secret) { 315 dprint(2, 316 ("sctp_process_heartbeat: invalid secret in ack %p\n", 317 (void *)sctp)); 318 return; 319 } 320 321 /* This address is now confirmed and alive. */ 322 sctp_faddr_alive(sctp, fp); 323 now = lbolt64; 324 sctp_update_rtt(sctp, fp, now - sent); 325 326 /* 327 * Note that the heartbeat timer should still be running, we don't 328 * reset it to avoid going through the whole list of peer addresses 329 * for each heartbeat ack as we probably are in interrupt context. 330 */ 331 fp->hb_expiry = now + SET_HB_INTVL(fp); 332 } 333