Deleted Added
full compact
sctputil.c (205627) sctputil.c (206137)
1/*-
2 * Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * a) Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.

--- 17 unchanged lines hidden (view full) ---

26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28 * THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31/* $KAME: sctputil.c,v 1.37 2005/03/07 23:26:09 itojun Exp $ */
32
33#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * a) Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.

--- 17 unchanged lines hidden (view full) ---

26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28 * THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31/* $KAME: sctputil.c,v 1.37 2005/03/07 23:26:09 itojun Exp $ */
32
33#include <sys/cdefs.h>
34__FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 205627 2010-03-24 19:45:36Z rrs $");
34__FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 206137 2010-04-03 15:40:14Z tuexen $");
35
36#include <netinet/sctp_os.h>
37#include <netinet/sctp_pcb.h>
38#include <netinet/sctputil.h>
39#include <netinet/sctp_var.h>
40#include <netinet/sctp_sysctl.h>
41#ifdef INET6
42#endif

--- 4 unchanged lines hidden (view full) ---

47#include <netinet/sctp_indata.h>/* for sctp_deliver_data() */
48#include <netinet/sctp_auth.h>
49#include <netinet/sctp_asconf.h>
50#include <netinet/sctp_cc_functions.h>
51
52#define NUMBER_OF_MTU_SIZES 18
53
54
35
36#include <netinet/sctp_os.h>
37#include <netinet/sctp_pcb.h>
38#include <netinet/sctputil.h>
39#include <netinet/sctp_var.h>
40#include <netinet/sctp_sysctl.h>
41#ifdef INET6
42#endif

--- 4 unchanged lines hidden (view full) ---

47#include <netinet/sctp_indata.h>/* for sctp_deliver_data() */
48#include <netinet/sctp_auth.h>
49#include <netinet/sctp_asconf.h>
50#include <netinet/sctp_cc_functions.h>
51
52#define NUMBER_OF_MTU_SIZES 18
53
54
55#if defined(__Windows__) && !defined(SCTP_LOCAL_TRACE_BUF)
56#include "eventrace_netinet.h"
57#include "sctputil.tmh" /* this is the file that will be auto
58 * generated */
59#else
55#ifndef KTR_SCTP
56#define KTR_SCTP KTR_SUBSYS
57#endif
60#ifndef KTR_SCTP
61#define KTR_SCTP KTR_SUBSYS
62#endif
63#endif
58
59void
60sctp_sblog(struct sockbuf *sb,
61 struct sctp_tcb *stcb, int from, int incr)
62{
63 struct sctp_cwnd_log sctp_clog;
64
65 sctp_clog.x.sb.stcb = stcb;

--- 798 unchanged lines hidden (view full) ---

864 not_done = 0;
865 }
866 }
867 return (x);
868}
869
870int
871sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb,
64
65void
66sctp_sblog(struct sockbuf *sb,
67 struct sctp_tcb *stcb, int from, int incr)
68{
69 struct sctp_cwnd_log sctp_clog;
70
71 sctp_clog.x.sb.stcb = stcb;

--- 798 unchanged lines hidden (view full) ---

870 not_done = 0;
871 }
872 }
873 return (x);
874}
875
876int
877sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb,
872 int for_a_init, uint32_t override_tag, uint32_t vrf_id)
878 uint32_t override_tag, uint32_t vrf_id)
873{
874 struct sctp_association *asoc;
875
876 /*
877 * Anything set to zero is taken care of by the allocation routine's
878 * bzero
879 */
880

--- 246 unchanged lines hidden (view full) ---

1127 SCTP_MALLOC(asoc->mapping_array, uint8_t *, asoc->mapping_array_size,
1128 SCTP_M_MAP);
1129 if (asoc->mapping_array == NULL) {
1130 SCTP_FREE(asoc->strmout, SCTP_M_STRMO);
1131 SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOMEM);
1132 return (ENOMEM);
1133 }
1134 memset(asoc->mapping_array, 0, asoc->mapping_array_size);
879{
880 struct sctp_association *asoc;
881
882 /*
883 * Anything set to zero is taken care of by the allocation routine's
884 * bzero
885 */
886

--- 246 unchanged lines hidden (view full) ---

1133 SCTP_MALLOC(asoc->mapping_array, uint8_t *, asoc->mapping_array_size,
1134 SCTP_M_MAP);
1135 if (asoc->mapping_array == NULL) {
1136 SCTP_FREE(asoc->strmout, SCTP_M_STRMO);
1137 SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOMEM);
1138 return (ENOMEM);
1139 }
1140 memset(asoc->mapping_array, 0, asoc->mapping_array_size);
1135 /* EY - initialize the nr_mapping_array just like mapping array */
1136 asoc->nr_mapping_array_size = SCTP_INITIAL_NR_MAPPING_ARRAY;
1137 SCTP_MALLOC(asoc->nr_mapping_array, uint8_t *, asoc->nr_mapping_array_size,
1141 SCTP_MALLOC(asoc->nr_mapping_array, uint8_t *, asoc->mapping_array_size,
1138 SCTP_M_MAP);
1139 if (asoc->nr_mapping_array == NULL) {
1140 SCTP_FREE(asoc->strmout, SCTP_M_STRMO);
1141 SCTP_FREE(asoc->mapping_array, SCTP_M_MAP);
1142 SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOMEM);
1143 return (ENOMEM);
1144 }
1142 SCTP_M_MAP);
1143 if (asoc->nr_mapping_array == NULL) {
1144 SCTP_FREE(asoc->strmout, SCTP_M_STRMO);
1145 SCTP_FREE(asoc->mapping_array, SCTP_M_MAP);
1146 SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOMEM);
1147 return (ENOMEM);
1148 }
1145 memset(asoc->nr_mapping_array, 0, asoc->nr_mapping_array_size);
1149 memset(asoc->nr_mapping_array, 0, asoc->mapping_array_size);
1146
1147 /* Now the init of the other outqueues */
1148 TAILQ_INIT(&asoc->free_chunks);
1149 TAILQ_INIT(&asoc->out_wheel);
1150 TAILQ_INIT(&asoc->control_send_queue);
1151 TAILQ_INIT(&asoc->asconf_send_queue);
1152 TAILQ_INIT(&asoc->send_queue);
1153 TAILQ_INIT(&asoc->sent_queue);

--- 48 unchanged lines hidden (view full) ---

1202 limit = 1;
1203 for (i = 0; i < limit; i++) {
1204 printf("%2.2x ", asoc->mapping_array[i]);
1205 if (((i + 1) % 16) == 0)
1206 printf("\n");
1207 }
1208 printf("\n");
1209 printf("NR Mapping size:%d baseTSN:%8.8x highestTSN:%8.8x\n",
1150
1151 /* Now the init of the other outqueues */
1152 TAILQ_INIT(&asoc->free_chunks);
1153 TAILQ_INIT(&asoc->out_wheel);
1154 TAILQ_INIT(&asoc->control_send_queue);
1155 TAILQ_INIT(&asoc->asconf_send_queue);
1156 TAILQ_INIT(&asoc->send_queue);
1157 TAILQ_INIT(&asoc->sent_queue);

--- 48 unchanged lines hidden (view full) ---

1206 limit = 1;
1207 for (i = 0; i < limit; i++) {
1208 printf("%2.2x ", asoc->mapping_array[i]);
1209 if (((i + 1) % 16) == 0)
1210 printf("\n");
1211 }
1212 printf("\n");
1213 printf("NR Mapping size:%d baseTSN:%8.8x highestTSN:%8.8x\n",
1210 asoc->nr_mapping_array_size,
1211 asoc->nr_mapping_array_base_tsn,
1214 asoc->mapping_array_size,
1215 asoc->mapping_array_base_tsn,
1212 asoc->highest_tsn_inside_nr_map
1213 );
1216 asoc->highest_tsn_inside_nr_map
1217 );
1214 limit = asoc->nr_mapping_array_size;
1215 for (i = asoc->nr_mapping_array_size; i >= 0; i--) {
1218 limit = asoc->mapping_array_size;
1219 for (i = asoc->mapping_array_size; i >= 0; i--) {
1216 if (asoc->nr_mapping_array[i]) {
1217 limit = i;
1218 break;
1219 }
1220 }
1221 if (limit == 0)
1222 limit = 1;
1223

--- 4 unchanged lines hidden (view full) ---

1228 }
1229 printf("\n");
1230}
1231
1232int
1233sctp_expand_mapping_array(struct sctp_association *asoc, uint32_t needed)
1234{
1235 /* mapping array needs to grow */
1220 if (asoc->nr_mapping_array[i]) {
1221 limit = i;
1222 break;
1223 }
1224 }
1225 if (limit == 0)
1226 limit = 1;
1227

--- 4 unchanged lines hidden (view full) ---

1232 }
1233 printf("\n");
1234}
1235
1236int
1237sctp_expand_mapping_array(struct sctp_association *asoc, uint32_t needed)
1238{
1239 /* mapping array needs to grow */
1236 uint8_t *new_array;
1240 uint8_t *new_array1, *new_array2;
1237 uint32_t new_size;
1238
1239
1240 new_size = asoc->mapping_array_size + ((needed + 7) / 8 + SCTP_MAPPING_ARRAY_INCR);
1241
1241 uint32_t new_size;
1242
1243
1244 new_size = asoc->mapping_array_size + ((needed + 7) / 8 + SCTP_MAPPING_ARRAY_INCR);
1245
1242 SCTP_MALLOC(new_array, uint8_t *, new_size, SCTP_M_MAP);
1243 if (new_array == NULL) {
1246 SCTP_MALLOC(new_array1, uint8_t *, new_size, SCTP_M_MAP);
1247 SCTP_MALLOC(new_array2, uint8_t *, new_size, SCTP_M_MAP);
1248 if ((new_array1 == NULL) || (new_array2 == NULL)) {
1244 /* can't get more, forget it */
1249 /* can't get more, forget it */
1245 SCTP_PRINTF("No memory for expansion of SCTP mapping array %d\n",
1246 new_size);
1250 SCTP_PRINTF("No memory for expansion of SCTP mapping array %d\n", new_size);
1251 if (new_array1) {
1252 SCTP_FREE(new_array1, SCTP_M_MAP);
1253 }
1254 if (new_array2) {
1255 SCTP_FREE(new_array2, SCTP_M_MAP);
1256 }
1247 return (-1);
1248 }
1257 return (-1);
1258 }
1249 memset(new_array, 0, new_size);
1250 memcpy(new_array, asoc->mapping_array, asoc->mapping_array_size);
1259 memset(new_array1, 0, new_size);
1260 memset(new_array2, 0, new_size);
1261 memcpy(new_array1, asoc->mapping_array, asoc->mapping_array_size);
1262 memcpy(new_array2, asoc->nr_mapping_array, asoc->mapping_array_size);
1251 SCTP_FREE(asoc->mapping_array, SCTP_M_MAP);
1263 SCTP_FREE(asoc->mapping_array, SCTP_M_MAP);
1252 asoc->mapping_array = new_array;
1253 asoc->mapping_array_size = new_size;
1254 new_size = asoc->nr_mapping_array_size + ((needed + 7) / 8 + SCTP_NR_MAPPING_ARRAY_INCR);
1255 SCTP_MALLOC(new_array, uint8_t *, new_size, SCTP_M_MAP);
1256 if (new_array == NULL) {
1257 /* can't get more, forget it */
1258 SCTP_PRINTF("No memory for expansion of SCTP mapping array %d\n",
1259 new_size);
1260 return (-1);
1261 }
1262 memset(new_array, 0, new_size);
1263 memcpy(new_array, asoc->nr_mapping_array, asoc->nr_mapping_array_size);
1264 SCTP_FREE(asoc->nr_mapping_array, SCTP_M_MAP);
1264 SCTP_FREE(asoc->nr_mapping_array, SCTP_M_MAP);
1265 asoc->nr_mapping_array = new_array;
1266 asoc->nr_mapping_array_size = new_size;
1265 asoc->mapping_array = new_array1;
1266 asoc->nr_mapping_array = new_array2;
1267 asoc->mapping_array_size = new_size;
1267 return (0);
1268}
1269
1270
1271#if defined(SCTP_USE_THREAD_BASED_ITERATOR)
1272static void
1273sctp_iterator_work(struct sctp_iterator *it)
1274{

--- 404 unchanged lines hidden (view full) ---

1679 }
1680 /* We do output but not here */
1681 did_output = 0;
1682 break;
1683 case SCTP_TIMER_TYPE_RECV:
1684 if ((stcb == NULL) || (inp == NULL)) {
1685 break;
1686 } {
1268 return (0);
1269}
1270
1271
1272#if defined(SCTP_USE_THREAD_BASED_ITERATOR)
1273static void
1274sctp_iterator_work(struct sctp_iterator *it)
1275{

--- 404 unchanged lines hidden (view full) ---

1680 }
1681 /* We do output but not here */
1682 did_output = 0;
1683 break;
1684 case SCTP_TIMER_TYPE_RECV:
1685 if ((stcb == NULL) || (inp == NULL)) {
1686 break;
1687 } {
1687 int abort_flag;
1688
1689 SCTP_STAT_INCR(sctps_timosack);
1690 stcb->asoc.timosack++;
1688 SCTP_STAT_INCR(sctps_timosack);
1689 stcb->asoc.timosack++;
1691 if (stcb->asoc.cumulative_tsn != stcb->asoc.highest_tsn_inside_map)
1692 sctp_sack_check(stcb, 0, 0, &abort_flag);
1693
1694 /*
1695 * EY if nr_sacks used then send an nr-sack , a sack
1696 * otherwise
1697 */
1698 if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && stcb->asoc.peer_supports_nr_sack)
1699 sctp_send_nr_sack(stcb);
1700 else
1701 sctp_send_sack(stcb);
1690 sctp_send_sack(stcb);
1702 }
1703#ifdef SCTP_AUDITING_ENABLED
1704 sctp_auditing(4, inp, stcb, net);
1705#endif
1706 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_SACK_TMR, SCTP_SO_NOT_LOCKED);
1707 break;
1708 case SCTP_TIMER_TYPE_SHUTDOWN:
1709 if ((stcb == NULL) || (inp == NULL)) {

--- 3043 unchanged lines hidden (view full) ---

4753next_on_sent:
4754 tp1 = TAILQ_FIRST(&stcb->asoc.send_queue);
4755 /*
4756 * recurse throught the send_queue too, starting at the
4757 * beginning.
4758 */
4759 if ((tp1) &&
4760 (tp1->rec.data.stream_number == stream) &&
1691 }
1692#ifdef SCTP_AUDITING_ENABLED
1693 sctp_auditing(4, inp, stcb, net);
1694#endif
1695 sctp_chunk_output(inp, stcb, SCTP_OUTPUT_FROM_SACK_TMR, SCTP_SO_NOT_LOCKED);
1696 break;
1697 case SCTP_TIMER_TYPE_SHUTDOWN:
1698 if ((stcb == NULL) || (inp == NULL)) {

--- 3043 unchanged lines hidden (view full) ---

4742next_on_sent:
4743 tp1 = TAILQ_FIRST(&stcb->asoc.send_queue);
4744 /*
4745 * recurse throught the send_queue too, starting at the
4746 * beginning.
4747 */
4748 if ((tp1) &&
4749 (tp1->rec.data.stream_number == stream) &&
4761 (tp1->rec.data.stream_seq == seq)
4762 ) {
4750 (tp1->rec.data.stream_seq == seq)) {
4763 /*
4764 * save to chk in case we have some on stream out
4765 * queue. If so and we have an un-transmitted one we
4766 * don't have to fudge the TSN.
4767 */
4768 chk = tp1;
4769 ret_sz += tp1->book_size;
4770 sctp_free_bufspace(stcb, &stcb->asoc, tp1, 1);

--- 326 unchanged lines hidden (view full) ---

5097 }
5098 SCTP_TCB_LOCK(stcb);
5099 if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
5100 /* No reports here */
5101 SCTP_TCB_UNLOCK(stcb);
5102 goto out;
5103 }
5104 SCTP_STAT_INCR(sctps_wu_sacks_sent);
4751 /*
4752 * save to chk in case we have some on stream out
4753 * queue. If so and we have an un-transmitted one we
4754 * don't have to fudge the TSN.
4755 */
4756 chk = tp1;
4757 ret_sz += tp1->book_size;
4758 sctp_free_bufspace(stcb, &stcb->asoc, tp1, 1);

--- 326 unchanged lines hidden (view full) ---

5085 }
5086 SCTP_TCB_LOCK(stcb);
5087 if (stcb->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
5088 /* No reports here */
5089 SCTP_TCB_UNLOCK(stcb);
5090 goto out;
5091 }
5092 SCTP_STAT_INCR(sctps_wu_sacks_sent);
5105 /*
5106 * EY if nr_sacks used then send an nr-sack , a sack
5107 * otherwise
5108 */
5109 if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off) && stcb->asoc.peer_supports_nr_sack)
5110 sctp_send_nr_sack(stcb);
5111 else
5112 sctp_send_sack(stcb);
5093 sctp_send_sack(stcb);
5113
5114 sctp_chunk_output(stcb->sctp_ep, stcb,
5115 SCTP_OUTPUT_FROM_USR_RCVD, SCTP_SO_LOCKED);
5116 /* make sure no timer is running */
5117 sctp_timer_stop(SCTP_TIMER_TYPE_RECV, stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTPUTIL + SCTP_LOC_6);
5118 SCTP_TCB_UNLOCK(stcb);
5119 } else {
5120 /* Update how much we have pending */

--- 353 unchanged lines hidden (view full) ---

5474 */
5475 control = ctl;
5476 goto found_one;
5477 } else if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS)) &&
5478 (ctl->length) &&
5479 ((ctl->some_taken) ||
5480 ((ctl->do_not_ref_stcb == 0) &&
5481 ((ctl->spec_flags & M_NOTIFICATION) == 0) &&
5094
5095 sctp_chunk_output(stcb->sctp_ep, stcb,
5096 SCTP_OUTPUT_FROM_USR_RCVD, SCTP_SO_LOCKED);
5097 /* make sure no timer is running */
5098 sctp_timer_stop(SCTP_TIMER_TYPE_RECV, stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTPUTIL + SCTP_LOC_6);
5099 SCTP_TCB_UNLOCK(stcb);
5100 } else {
5101 /* Update how much we have pending */

--- 353 unchanged lines hidden (view full) ---

5455 */
5456 control = ctl;
5457 goto found_one;
5458 } else if ((sctp_is_feature_on(inp, SCTP_PCB_FLAGS_INTERLEAVE_STRMS)) &&
5459 (ctl->length) &&
5460 ((ctl->some_taken) ||
5461 ((ctl->do_not_ref_stcb == 0) &&
5462 ((ctl->spec_flags & M_NOTIFICATION) == 0) &&
5482 (ctl->stcb->asoc.strmin[ctl->sinfo_stream].delivery_started == 0)))
5483 ) {
5463 (ctl->stcb->asoc.strmin[ctl->sinfo_stream].delivery_started == 0)))) {
5484 /*-
5485 * If we have the same tcb, and there is data present, and we
5486 * have the strm interleave feature present. Then if we have
5487 * taken some (pdapi) or we can refer to tht tcb AND we have
5488 * not started a delivery for this stream, we can take it.
5489 * Note we do NOT allow a notificaiton on the same assoc to
5490 * be delivered.
5491 */

--- 442 unchanged lines hidden (view full) ---

5934 SCTP_INP_READ_UNLOCK(inp);
5935 hold_rlock = 0;
5936 }
5937 if (hold_sblock == 0) {
5938 SOCKBUF_LOCK(&so->so_rcv);
5939 hold_sblock = 1;
5940 }
5941 if ((copied_so_far) && (control->length == 0) &&
5464 /*-
5465 * If we have the same tcb, and there is data present, and we
5466 * have the strm interleave feature present. Then if we have
5467 * taken some (pdapi) or we can refer to tht tcb AND we have
5468 * not started a delivery for this stream, we can take it.
5469 * Note we do NOT allow a notificaiton on the same assoc to
5470 * be delivered.
5471 */

--- 442 unchanged lines hidden (view full) ---

5914 SCTP_INP_READ_UNLOCK(inp);
5915 hold_rlock = 0;
5916 }
5917 if (hold_sblock == 0) {
5918 SOCKBUF_LOCK(&so->so_rcv);
5919 hold_sblock = 1;
5920 }
5921 if ((copied_so_far) && (control->length == 0) &&
5942 (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE))
5943 ) {
5922 (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_FRAG_INTERLEAVE))) {
5944 goto release;
5945 }
5946 if (so->so_rcv.sb_cc <= control->held_length) {
5947 error = sbwait(&so->so_rcv);
5948 if (error) {
5949 goto release;
5950 }
5951 control->held_length = 0;

--- 1027 unchanged lines hidden ---
5923 goto release;
5924 }
5925 if (so->so_rcv.sb_cc <= control->held_length) {
5926 error = sbwait(&so->so_rcv);
5927 if (error) {
5928 goto release;
5929 }
5930 control->held_length = 0;

--- 1027 unchanged lines hidden ---