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