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 --- |