output.c (a29a5bd4f5c3e8ba2e89688feab8b01c44f1654f) | output.c (4cd57c8078fae0a4b1bf421191e94626d0cba92a) |
---|---|
1/* SCTP kernel reference Implementation 2 * (C) Copyright IBM Corp. 2001, 2004 3 * Copyright (c) 1999-2000 Cisco, Inc. 4 * Copyright (c) 1999-2001 Motorola, Inc. 5 * 6 * This file is part of the SCTP kernel reference Implementation 7 * 8 * These functions handle output processing. --- 66 unchanged lines hidden (view full) --- 75 76 SCTP_DEBUG_PRINTK("%s: packet:%p vtag:0x%x\n", __FUNCTION__, 77 packet, vtag); 78 79 packet->vtag = vtag; 80 packet->has_cookie_echo = 0; 81 packet->has_sack = 0; 82 packet->has_auth = 0; | 1/* SCTP kernel reference Implementation 2 * (C) Copyright IBM Corp. 2001, 2004 3 * Copyright (c) 1999-2000 Cisco, Inc. 4 * Copyright (c) 1999-2001 Motorola, Inc. 5 * 6 * This file is part of the SCTP kernel reference Implementation 7 * 8 * These functions handle output processing. --- 66 unchanged lines hidden (view full) --- 75 76 SCTP_DEBUG_PRINTK("%s: packet:%p vtag:0x%x\n", __FUNCTION__, 77 packet, vtag); 78 79 packet->vtag = vtag; 80 packet->has_cookie_echo = 0; 81 packet->has_sack = 0; 82 packet->has_auth = 0; |
83 packet->has_data = 0; |
|
83 packet->ipfragok = 0; 84 packet->auth = NULL; 85 86 if (ecn_capable && sctp_packet_empty(packet)) { 87 chunk = sctp_get_ecne_prepend(packet->transport->asoc); 88 89 /* If there a is a prepend chunk stick it on the list before 90 * any other chunks get appended. --- 28 unchanged lines hidden (view full) --- 119 } 120 overhead += sizeof(struct sctphdr); 121 packet->overhead = overhead; 122 packet->size = overhead; 123 packet->vtag = 0; 124 packet->has_cookie_echo = 0; 125 packet->has_sack = 0; 126 packet->has_auth = 0; | 84 packet->ipfragok = 0; 85 packet->auth = NULL; 86 87 if (ecn_capable && sctp_packet_empty(packet)) { 88 chunk = sctp_get_ecne_prepend(packet->transport->asoc); 89 90 /* If there a is a prepend chunk stick it on the list before 91 * any other chunks get appended. --- 28 unchanged lines hidden (view full) --- 120 } 121 overhead += sizeof(struct sctphdr); 122 packet->overhead = overhead; 123 packet->size = overhead; 124 packet->vtag = 0; 125 packet->has_cookie_echo = 0; 126 packet->has_sack = 0; 127 packet->has_auth = 0; |
128 packet->has_data = 0; |
|
127 packet->ipfragok = 0; 128 packet->malloced = 0; 129 packet->auth = NULL; 130 return packet; 131} 132 133/* Free a packet. */ 134void sctp_packet_free(struct sctp_packet *packet) --- 45 unchanged lines hidden (view full) --- 180 case SCTP_XMIT_OK: 181 case SCTP_XMIT_NAGLE_DELAY: 182 break; 183 } 184 185 return retval; 186} 187 | 129 packet->ipfragok = 0; 130 packet->malloced = 0; 131 packet->auth = NULL; 132 return packet; 133} 134 135/* Free a packet. */ 136void sctp_packet_free(struct sctp_packet *packet) --- 45 unchanged lines hidden (view full) --- 182 case SCTP_XMIT_OK: 183 case SCTP_XMIT_NAGLE_DELAY: 184 break; 185 } 186 187 return retval; 188} 189 |
190/* Try to bundle an auth chunk into the packet. */ 191static sctp_xmit_t sctp_packet_bundle_auth(struct sctp_packet *pkt, 192 struct sctp_chunk *chunk) 193{ 194 struct sctp_association *asoc = pkt->transport->asoc; 195 struct sctp_chunk *auth; 196 sctp_xmit_t retval = SCTP_XMIT_OK; 197 198 /* if we don't have an association, we can't do authentication */ 199 if (!asoc) 200 return retval; 201 202 /* See if this is an auth chunk we are bundling or if 203 * auth is already bundled. 204 */ 205 if (chunk->chunk_hdr->type == SCTP_CID_AUTH || pkt->auth) 206 return retval; 207 208 /* if the peer did not request this chunk to be authenticated, 209 * don't do it 210 */ 211 if (!chunk->auth) 212 return retval; 213 214 auth = sctp_make_auth(asoc); 215 if (!auth) 216 return retval; 217 218 retval = sctp_packet_append_chunk(pkt, auth); 219 220 return retval; 221} 222 |
|
188/* Try to bundle a SACK with the packet. */ 189static sctp_xmit_t sctp_packet_bundle_sack(struct sctp_packet *pkt, 190 struct sctp_chunk *chunk) 191{ 192 sctp_xmit_t retval = SCTP_XMIT_OK; 193 194 /* If sending DATA and haven't aleady bundled a SACK, try to 195 * bundle one in to the packet. --- 30 unchanged lines hidden (view full) --- 226 __u16 chunk_len = WORD_ROUND(ntohs(chunk->chunk_hdr->length)); 227 size_t psize; 228 size_t pmtu; 229 int too_big; 230 231 SCTP_DEBUG_PRINTK("%s: packet:%p chunk:%p\n", __FUNCTION__, packet, 232 chunk); 233 | 223/* Try to bundle a SACK with the packet. */ 224static sctp_xmit_t sctp_packet_bundle_sack(struct sctp_packet *pkt, 225 struct sctp_chunk *chunk) 226{ 227 sctp_xmit_t retval = SCTP_XMIT_OK; 228 229 /* If sending DATA and haven't aleady bundled a SACK, try to 230 * bundle one in to the packet. --- 30 unchanged lines hidden (view full) --- 261 __u16 chunk_len = WORD_ROUND(ntohs(chunk->chunk_hdr->length)); 262 size_t psize; 263 size_t pmtu; 264 int too_big; 265 266 SCTP_DEBUG_PRINTK("%s: packet:%p chunk:%p\n", __FUNCTION__, packet, 267 chunk); 268 |
234 retval = sctp_packet_bundle_sack(packet, chunk); 235 psize = packet->size; | 269 /* Try to bundle AUTH chunk */ 270 retval = sctp_packet_bundle_auth(packet, chunk); 271 if (retval != SCTP_XMIT_OK) 272 goto finish; |
236 | 273 |
274 /* Try to bundle SACK chunk */ 275 retval = sctp_packet_bundle_sack(packet, chunk); |
|
237 if (retval != SCTP_XMIT_OK) 238 goto finish; 239 | 276 if (retval != SCTP_XMIT_OK) 277 goto finish; 278 |
279 psize = packet->size; |
|
240 pmtu = ((packet->transport->asoc) ? 241 (packet->transport->asoc->pathmtu) : 242 (packet->transport->pathmtu)); 243 244 too_big = (psize + chunk_len > pmtu); 245 246 /* Decide if we need to fragment or resubmit later. */ 247 if (too_big) { | 280 pmtu = ((packet->transport->asoc) ? 281 (packet->transport->asoc->pathmtu) : 282 (packet->transport->pathmtu)); 283 284 too_big = (psize + chunk_len > pmtu); 285 286 /* Decide if we need to fragment or resubmit later. */ 287 if (too_big) { |
248 /* Both control chunks and data chunks with TSNs are 249 * non-fragmentable. | 288 /* It's OK to fragmet at IP level if any one of the following 289 * is true: 290 * 1. The packet is empty (meaning this chunk is greater 291 * the MTU) 292 * 2. The chunk we are adding is a control chunk 293 * 3. The packet doesn't have any data in it yet and data 294 * requires authentication. |
250 */ | 295 */ |
251 if (sctp_packet_empty(packet) || !sctp_chunk_is_data(chunk)) { | 296 if (sctp_packet_empty(packet) || !sctp_chunk_is_data(chunk) || 297 (!packet->has_data && chunk->auth)) { |
252 /* We no longer do re-fragmentation. 253 * Just fragment at the IP layer, if we 254 * actually hit this condition 255 */ 256 packet->ipfragok = 1; 257 goto append; 258 259 } else { --- 5 unchanged lines hidden (view full) --- 265append: 266 /* We believe that this chunk is OK to add to the packet (as 267 * long as we have the cwnd for it). 268 */ 269 270 /* DATA is a special case since we must examine both rwnd and cwnd 271 * before we send DATA. 272 */ | 298 /* We no longer do re-fragmentation. 299 * Just fragment at the IP layer, if we 300 * actually hit this condition 301 */ 302 packet->ipfragok = 1; 303 goto append; 304 305 } else { --- 5 unchanged lines hidden (view full) --- 311append: 312 /* We believe that this chunk is OK to add to the packet (as 313 * long as we have the cwnd for it). 314 */ 315 316 /* DATA is a special case since we must examine both rwnd and cwnd 317 * before we send DATA. 318 */ |
273 if (sctp_chunk_is_data(chunk)) { | 319 switch (chunk->chunk_hdr->type) { 320 case SCTP_CID_DATA: |
274 retval = sctp_packet_append_data(packet, chunk); 275 /* Disallow SACK bundling after DATA. */ 276 packet->has_sack = 1; | 321 retval = sctp_packet_append_data(packet, chunk); 322 /* Disallow SACK bundling after DATA. */ 323 packet->has_sack = 1; |
324 /* Disallow AUTH bundling after DATA */ 325 packet->has_auth = 1; 326 /* Let it be knows that packet has DATA in it */ 327 packet->has_data = 1; |
|
277 if (SCTP_XMIT_OK != retval) 278 goto finish; | 328 if (SCTP_XMIT_OK != retval) 329 goto finish; |
279 } else if (SCTP_CID_COOKIE_ECHO == chunk->chunk_hdr->type) | 330 break; 331 case SCTP_CID_COOKIE_ECHO: |
280 packet->has_cookie_echo = 1; | 332 packet->has_cookie_echo = 1; |
281 else if (SCTP_CID_SACK == chunk->chunk_hdr->type) | 333 break; 334 335 case SCTP_CID_SACK: |
282 packet->has_sack = 1; | 336 packet->has_sack = 1; |
337 break; |
|
283 | 338 |
339 case SCTP_CID_AUTH: 340 packet->has_auth = 1; 341 packet->auth = chunk; 342 break; 343 } 344 |
|
284 /* It is OK to send this chunk. */ 285 list_add_tail(&chunk->list, &packet->chunk_list); 286 packet->size += chunk_len; 287 chunk->transport = packet->transport; 288finish: 289 return retval; 290} 291 --- 10 unchanged lines hidden (view full) --- 302 __u32 crc32 = 0; 303 struct sk_buff *nskb; 304 struct sctp_chunk *chunk, *tmp; 305 struct sock *sk; 306 int err = 0; 307 int padding; /* How much padding do we need? */ 308 __u8 has_data = 0; 309 struct dst_entry *dst = tp->dst; | 345 /* It is OK to send this chunk. */ 346 list_add_tail(&chunk->list, &packet->chunk_list); 347 packet->size += chunk_len; 348 chunk->transport = packet->transport; 349finish: 350 return retval; 351} 352 --- 10 unchanged lines hidden (view full) --- 363 __u32 crc32 = 0; 364 struct sk_buff *nskb; 365 struct sctp_chunk *chunk, *tmp; 366 struct sock *sk; 367 int err = 0; 368 int padding; /* How much padding do we need? */ 369 __u8 has_data = 0; 370 struct dst_entry *dst = tp->dst; |
371 unsigned char *auth = NULL; /* pointer to auth in skb data */ 372 __u32 cksum_buf_len = sizeof(struct sctphdr); |
|
310 311 SCTP_DEBUG_PRINTK("%s: packet:%p\n", __FUNCTION__, packet); 312 313 /* Do NOT generate a chunkless packet. */ 314 if (list_empty(&packet->chunk_list)) 315 return err; 316 317 /* Set up convenience variables... */ --- 37 unchanged lines hidden (view full) --- 355 * transmitter shall: 356 * 357 * 1) Fill in the proper Verification Tag in the SCTP common 358 * header and initialize the checksum field to 0's. 359 */ 360 sh->vtag = htonl(packet->vtag); 361 sh->checksum = 0; 362 | 373 374 SCTP_DEBUG_PRINTK("%s: packet:%p\n", __FUNCTION__, packet); 375 376 /* Do NOT generate a chunkless packet. */ 377 if (list_empty(&packet->chunk_list)) 378 return err; 379 380 /* Set up convenience variables... */ --- 37 unchanged lines hidden (view full) --- 418 * transmitter shall: 419 * 420 * 1) Fill in the proper Verification Tag in the SCTP common 421 * header and initialize the checksum field to 0's. 422 */ 423 sh->vtag = htonl(packet->vtag); 424 sh->checksum = 0; 425 |
363 /* 2) Calculate the Adler-32 checksum of the whole packet, 364 * including the SCTP common header and all the 365 * chunks. 366 * 367 * Note: Adler-32 is no longer applicable, as has been replaced 368 * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>. 369 */ 370 if (!(dst->dev->features & NETIF_F_NO_CSUM)) 371 crc32 = sctp_start_cksum((__u8 *)sh, sizeof(struct sctphdr)); 372 | |
373 /** 374 * 6.10 Bundling 375 * 376 * An endpoint bundles chunks by simply including multiple 377 * chunks in one outbound SCTP packet. ... 378 */ 379 380 /** --- 34 unchanged lines hidden (view full) --- 415 chunk->sent_at = jiffies; 416 has_data = 1; 417 } 418 419 padding = WORD_ROUND(chunk->skb->len) - chunk->skb->len; 420 if (padding) 421 memset(skb_put(chunk->skb, padding), 0, padding); 422 | 426 /** 427 * 6.10 Bundling 428 * 429 * An endpoint bundles chunks by simply including multiple 430 * chunks in one outbound SCTP packet. ... 431 */ 432 433 /** --- 34 unchanged lines hidden (view full) --- 468 chunk->sent_at = jiffies; 469 has_data = 1; 470 } 471 472 padding = WORD_ROUND(chunk->skb->len) - chunk->skb->len; 473 if (padding) 474 memset(skb_put(chunk->skb, padding), 0, padding); 475 |
423 if (dst->dev->features & NETIF_F_NO_CSUM) 424 memcpy(skb_put(nskb, chunk->skb->len), | 476 /* if this is the auth chunk that we are adding, 477 * store pointer where it will be added and put 478 * the auth into the packet. 479 */ 480 if (chunk == packet->auth) 481 auth = skb_tail_pointer(nskb); 482 483 cksum_buf_len += chunk->skb->len; 484 memcpy(skb_put(nskb, chunk->skb->len), |
425 chunk->skb->data, chunk->skb->len); | 485 chunk->skb->data, chunk->skb->len); |
426 else 427 crc32 = sctp_update_copy_cksum(skb_put(nskb, 428 chunk->skb->len), 429 chunk->skb->data, 430 chunk->skb->len, crc32); | |
431 432 SCTP_DEBUG_PRINTK("%s %p[%s] %s 0x%x, %s %d, %s %d, %s %d\n", 433 "*** Chunk", chunk, 434 sctp_cname(SCTP_ST_CHUNK( 435 chunk->chunk_hdr->type)), 436 chunk->has_tsn ? "TSN" : "No TSN", 437 chunk->has_tsn ? 438 ntohl(chunk->subh.data_hdr->tsn) : 0, --- 5 unchanged lines hidden (view full) --- 444 * If this is a control chunk, this is our last 445 * reference. Free data chunks after they've been 446 * acknowledged or have failed. 447 */ 448 if (!sctp_chunk_is_data(chunk)) 449 sctp_chunk_free(chunk); 450 } 451 | 486 487 SCTP_DEBUG_PRINTK("%s %p[%s] %s 0x%x, %s %d, %s %d, %s %d\n", 488 "*** Chunk", chunk, 489 sctp_cname(SCTP_ST_CHUNK( 490 chunk->chunk_hdr->type)), 491 chunk->has_tsn ? "TSN" : "No TSN", 492 chunk->has_tsn ? 493 ntohl(chunk->subh.data_hdr->tsn) : 0, --- 5 unchanged lines hidden (view full) --- 499 * If this is a control chunk, this is our last 500 * reference. Free data chunks after they've been 501 * acknowledged or have failed. 502 */ 503 if (!sctp_chunk_is_data(chunk)) 504 sctp_chunk_free(chunk); 505 } 506 |
452 /* Perform final transformation on checksum. */ 453 if (!(dst->dev->features & NETIF_F_NO_CSUM)) | 507 /* SCTP-AUTH, Section 6.2 508 * The sender MUST calculate the MAC as described in RFC2104 [2] 509 * using the hash function H as described by the MAC Identifier and 510 * the shared association key K based on the endpoint pair shared key 511 * described by the shared key identifier. The 'data' used for the 512 * computation of the AUTH-chunk is given by the AUTH chunk with its 513 * HMAC field set to zero (as shown in Figure 6) followed by all 514 * chunks that are placed after the AUTH chunk in the SCTP packet. 515 */ 516 if (auth) 517 sctp_auth_calculate_hmac(asoc, nskb, 518 (struct sctp_auth_chunk *)auth, 519 GFP_ATOMIC); 520 521 /* 2) Calculate the Adler-32 checksum of the whole packet, 522 * including the SCTP common header and all the 523 * chunks. 524 * 525 * Note: Adler-32 is no longer applicable, as has been replaced 526 * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>. 527 */ 528 if (!(dst->dev->features & NETIF_F_NO_CSUM)) { 529 crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len); |
454 crc32 = sctp_end_cksum(crc32); | 530 crc32 = sctp_end_cksum(crc32); |
531 } |
|
455 456 /* 3) Put the resultant value into the checksum field in the 457 * common header, and leave the rest of the bits unchanged. 458 */ 459 sh->checksum = htonl(crc32); 460 461 /* IP layer ECN support 462 * From RFC 2481 --- 209 unchanged lines hidden --- | 532 533 /* 3) Put the resultant value into the checksum field in the 534 * common header, and leave the rest of the bits unchanged. 535 */ 536 sh->checksum = htonl(crc32); 537 538 /* IP layer ECN support 539 * From RFC 2481 --- 209 unchanged lines hidden --- |