diff options
author | t00fcxen <t00fcxen@9df1edf5-d72c-5b5f-11c0-5f5209eb73f7> | 2014-08-13 16:03:20 +0000 |
---|---|---|
committer | t00fcxen <t00fcxen@9df1edf5-d72c-5b5f-11c0-5f5209eb73f7> | 2014-08-13 16:03:20 +0000 |
commit | 20d5d287bff2075897105f85287230d55bdfa420 (patch) | |
tree | c17e755b278ce91d9a7a6a61efe15eadb87bd30b | |
parent | 0602fd0eeb08e1999c7f28f21c8dde1f4503a03f (diff) | |
download | usrsctplib-20d5d287bff2075897105f85287230d55bdfa420.tar.gz |
Sync with Mavericks sources.
git-svn-id: http://sctp-refimpl.googlecode.com/svn/trunk/KERN/usrsctp/usrsctplib@8968 9df1edf5-d72c-5b5f-11c0-5f5209eb73f7
-rwxr-xr-x | netinet/sctp.h | 4 | ||||
-rwxr-xr-x | netinet/sctp_input.c | 14 | ||||
-rwxr-xr-x | netinet/sctp_output.c | 26 | ||||
-rwxr-xr-x | netinet/sctp_structs.h | 12 | ||||
-rwxr-xr-x | netinet/sctp_uio.h | 21 | ||||
-rwxr-xr-x | netinet/sctp_usrreq.c | 68 | ||||
-rwxr-xr-x | netinet/sctputil.c | 34 |
7 files changed, 169 insertions, 10 deletions
diff --git a/netinet/sctp.h b/netinet/sctp.h index f3c65de..a2ab878 100755 --- a/netinet/sctp.h +++ b/netinet/sctp.h @@ -32,7 +32,7 @@ #ifdef __FreeBSD__ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/sys/netinet/sctp.h 269858 2014-08-12 11:30:16Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctp.h 269945 2014-08-13 15:50:16Z tuexen $"); #endif #ifndef _NETINET_SCTP_H_ @@ -150,6 +150,8 @@ struct sctp_paramhdr { #define SCTP_GET_ASSOC_NUMBER 0x00000104 /* ro */ #define SCTP_GET_ASSOC_ID_LIST 0x00000105 /* ro */ #define SCTP_TIMEOUTS 0x00000106 +#define SCTP_PR_STREAM_STATUS 0x00000107 +#define SCTP_PR_ASSOC_STATUS 0x00000108 /* * user socket options: BSD implementation specific diff --git a/netinet/sctp_input.c b/netinet/sctp_input.c index 1517829..8373d63 100755 --- a/netinet/sctp_input.c +++ b/netinet/sctp_input.c @@ -32,7 +32,7 @@ #ifdef __FreeBSD__ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 269858 2014-08-12 11:30:16Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctp_input.c 269945 2014-08-13 15:50:16Z tuexen $"); #endif #include <netinet/sctp_os.h> @@ -1523,6 +1523,9 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset, int retval; int spec_flag = 0; uint32_t how_indx; +#if defined(SCTP_DETAILED_STR_STATS) + int j; +#endif net = *netp; /* I know that the TCB is non-NULL from the caller */ @@ -1983,6 +1986,15 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset, sctp_report_all_outbound(stcb, 0, 1, SCTP_SO_LOCKED); for (i = 0; i < stcb->asoc.streamoutcnt; i++) { stcb->asoc.strmout[i].chunks_on_queues = 0; +#if defined(SCTP_DETAILED_STR_STATS) + for (j = 0; j < SCTP_PR_SCTP_MAX + 1; j++) { + asoc->strmout[i].abandoned_sent[j] = 0; + asoc->strmout[i].abandoned_unsent[j] = 0; + } +#else + asoc->strmout[i].abandoned_sent[0] = 0; + asoc->strmout[i].abandoned_unsent[0] = 0; +#endif stcb->asoc.strmout[i].stream_no = i; stcb->asoc.strmout[i].next_sequence_send = 0; stcb->asoc.strmout[i].last_msg_incomplete = 0; diff --git a/netinet/sctp_output.c b/netinet/sctp_output.c index 4d76e7d..73e0a91 100755 --- a/netinet/sctp_output.c +++ b/netinet/sctp_output.c @@ -32,7 +32,7 @@ #ifdef __FreeBSD__ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 269858 2014-08-12 11:30:16Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 269945 2014-08-13 15:50:16Z tuexen $"); #endif #include <netinet/sctp_os.h> @@ -3707,6 +3707,9 @@ sctp_process_cmsgs_for_init(struct sctp_tcb *stcb, struct mbuf *control, int *er if (stcb->asoc.streamoutcnt < stcb->asoc.pre_open_streams) { struct sctp_stream_out *tmp_str; unsigned int i; +#if defined(SCTP_DETAILED_STR_STATS) + int j; +#endif /* Default is NOT correct */ SCTPDBG(SCTP_DEBUG_OUTPUT1, "Ok, default:%d pre_open:%d\n", @@ -3728,6 +3731,15 @@ sctp_process_cmsgs_for_init(struct sctp_tcb *stcb, struct mbuf *control, int *er TAILQ_INIT(&stcb->asoc.strmout[i].outqueue); stcb->asoc.strmout[i].chunks_on_queues = 0; stcb->asoc.strmout[i].next_sequence_send = 0; +#if defined(SCTP_DETAILED_STR_STATS) + for (j = 0; j < SCTP_PR_SCTP_MAX + 1; j++) { + stcb->asoc.strmout[i].abandoned_sent[j] = 0; + stcb->asoc.strmout[i].abandoned_unsent[j] = 0; + } +#else + stcb->asoc.strmout[i].abandoned_sent[0] = 0; + stcb->asoc.strmout[i].abandoned_unsent[0] = 0; +#endif stcb->asoc.strmout[i].stream_no = i; stcb->asoc.strmout[i].last_msg_incomplete = 0; stcb->asoc.ss_functions.sctp_ss_init_stream(&stcb->asoc.strmout[i], NULL); @@ -12571,6 +12583,9 @@ sctp_send_str_reset_req(struct sctp_tcb *stcb, struct sctp_stream_out *oldstream; struct sctp_stream_queue_pending *sp, *nsp; int i; +#if defined(SCTP_DETAILED_STR_STATS) + int j; +#endif oldstream = stcb->asoc.strmout; /* get some more */ @@ -12615,6 +12630,15 @@ sctp_send_str_reset_req(struct sctp_tcb *stcb, for (i = stcb->asoc.streamoutcnt; i < (stcb->asoc.streamoutcnt + adding_o); i++) { TAILQ_INIT(&stcb->asoc.strmout[i].outqueue); stcb->asoc.strmout[i].chunks_on_queues = 0; +#if defined(SCTP_DETAILED_STR_STATS) + for (j = 0; j < SCTP_PR_SCTP_MAX + 1; j++) { + stcb->asoc.strmout[i].abandoned_sent[j] = 0; + stcb->asoc.strmout[i].abandoned_unsent[j] = 0; + } +#else + stcb->asoc.strmout[i].abandoned_sent[0] = 0; + stcb->asoc.strmout[i].abandoned_unsent[0] = 0; +#endif stcb->asoc.strmout[i].next_sequence_send = 0x0; stcb->asoc.strmout[i].stream_no = i; stcb->asoc.strmout[i].last_msg_incomplete = 0; diff --git a/netinet/sctp_structs.h b/netinet/sctp_structs.h index 24bacb9..7214d8d 100755 --- a/netinet/sctp_structs.h +++ b/netinet/sctp_structs.h @@ -32,7 +32,7 @@ #ifdef __FreeBSD__ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/sys/netinet/sctp_structs.h 269858 2014-08-12 11:30:16Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctp_structs.h 269945 2014-08-13 15:50:16Z tuexen $"); #endif #ifndef _NETINET_SCTP_STRUCTS_H_ @@ -636,6 +636,14 @@ struct sctp_stream_out { struct sctp_streamhead outqueue; union scheduling_parameters ss_params; uint32_t chunks_on_queues; +#if defined(SCTP_DETAILED_STR_STATS) + uint32_t abandoned_unsent[SCTP_PR_SCTP_MAX + 1]; + uint32_t abandoned_sent[SCTP_PR_SCTP_MAX + 1]; +#else + /* Only the aggregation */ + uint32_t abandoned_unsent[1]; + uint32_t abandoned_sent[1]; +#endif uint16_t stream_no; uint16_t next_sequence_send; /* next one I expect to send out */ uint8_t last_msg_incomplete; @@ -1261,6 +1269,8 @@ struct sctp_association { uint32_t timoshutdownack; struct timeval start_time; struct timeval discontinuity_time; + uint64_t abandoned_unsent[SCTP_PR_SCTP_MAX + 1]; + uint64_t abandoned_sent[SCTP_PR_SCTP_MAX + 1]; }; #endif diff --git a/netinet/sctp_uio.h b/netinet/sctp_uio.h index 5e9ad19..7cf02ed 100755 --- a/netinet/sctp_uio.h +++ b/netinet/sctp_uio.h @@ -32,7 +32,7 @@ #ifdef __FreeBSD__ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/sys/netinet/sctp_uio.h 268990 2014-07-22 19:54:22Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctp_uio.h 269945 2014-08-13 15:50:16Z tuexen $"); #endif #ifndef _NETINET_SCTP_UIO_H_ @@ -279,18 +279,23 @@ struct sctp_snd_all_completes { SCTP_SACK_IMMEDIATELY)) != 0) /* for the endpoint */ -/* The lower byte is an enumeration of PR-SCTP policies */ +/* The lower four bits is an enumeration of PR-SCTP policies */ #define SCTP_PR_SCTP_NONE 0x0000 /* Reliable transfer */ #define SCTP_PR_SCTP_TTL 0x0001 /* Time based PR-SCTP */ #define SCTP_PR_SCTP_BUF 0x0002 /* Buffer based PR-SCTP */ #define SCTP_PR_SCTP_RTX 0x0003 /* Number of retransmissions based PR-SCTP */ +#define SCTP_PR_SCTP_MAX SCTP_PR_SCTP_RTX +#define SCTP_PR_SCTP_ALL 0x000f /* Used for aggregated stats */ #define PR_SCTP_POLICY(x) ((x) & 0x0f) -#define PR_SCTP_ENABLED(x) (PR_SCTP_POLICY(x) != SCTP_PR_SCTP_NONE) +#define PR_SCTP_ENABLED(x) ((PR_SCTP_POLICY(x) != SCTP_PR_SCTP_NONE) && \ + (PR_SCTP_POLICY(x) != SCTP_PR_SCTP_ALL)) #define PR_SCTP_TTL_ENABLED(x) (PR_SCTP_POLICY(x) == SCTP_PR_SCTP_TTL) #define PR_SCTP_BUF_ENABLED(x) (PR_SCTP_POLICY(x) == SCTP_PR_SCTP_BUF) #define PR_SCTP_RTX_ENABLED(x) (PR_SCTP_POLICY(x) == SCTP_PR_SCTP_RTX) -#define PR_SCTP_INVALID_POLICY(x) (PR_SCTP_POLICY(x) > SCTP_PR_SCTP_RTX) +#define PR_SCTP_INVALID_POLICY(x) (PR_SCTP_POLICY(x) > SCTP_PR_SCTP_MAX) +#define PR_SCTP_VALID_POLICY(x) (PR_SCTP_POLICY(x) <= SCTP_PR_SCTP_MAX) + /* Stat's */ struct sctp_pcbinfo { uint32_t ep_count; @@ -748,6 +753,14 @@ struct sctp_udpencaps { uint16_t sue_port; }; +struct sctp_prstatus { + sctp_assoc_t sprstat_assoc_id; + uint16_t sprstat_sid; + uint16_t sprstat_policy; + uint64_t sprstat_abandoned_unsent; + uint64_t sprstat_abandoned_sent; +}; + struct sctp_cwnd_args { struct sctp_nets *net; /* network to */ /* FIXME: LP64 issue */ uint32_t cwnd_new_value;/* cwnd in k */ diff --git a/netinet/sctp_usrreq.c b/netinet/sctp_usrreq.c index 879e7f1..0564d29 100755 --- a/netinet/sctp_usrreq.c +++ b/netinet/sctp_usrreq.c @@ -32,7 +32,7 @@ #ifdef __FreeBSD__ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/sys/netinet/sctp_usrreq.c 269858 2014-08-12 11:30:16Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctp_usrreq.c 269945 2014-08-13 15:50:16Z tuexen $"); #endif #include <netinet/sctp_os.h> @@ -4218,6 +4218,72 @@ sctp_getopt(struct socket *so, int optname, void *optval, size_t *optsize, } break; } + case SCTP_PR_STREAM_STATUS: + { + struct sctp_prstatus *sprstat; + uint16_t sid; + uint16_t policy; + + SCTP_CHECK_AND_CAST(sprstat, optval, struct sctp_prstatus, *optsize); + SCTP_FIND_STCB(inp, stcb, sprstat->sprstat_assoc_id); + + sid = sprstat->sprstat_sid; + policy = sprstat->sprstat_policy; +#if defined(SCTP_DETAILED_STR_STATS) + if ((stcb != NULL) && + (policy != SCTP_PR_SCTP_NONE) && + (sid < stcb->asoc.streamoutcnt) && + ((policy == SCTP_PR_SCTP_ALL) || + (PR_SCTP_VALID_POLICY(policy)))) { +#else + if ((stcb != NULL) && + (policy != SCTP_PR_SCTP_NONE) && + (sid < stcb->asoc.streamoutcnt) && + (policy == SCTP_PR_SCTP_ALL)) { +#endif + if (policy == SCTP_PR_SCTP_ALL) { + sprstat->sprstat_abandoned_unsent = stcb->asoc.strmout[sid].abandoned_unsent[0]; + sprstat->sprstat_abandoned_sent = stcb->asoc.strmout[sid].abandoned_sent[0]; + } else { + sprstat->sprstat_abandoned_unsent = stcb->asoc.strmout[sid].abandoned_unsent[policy]; + sprstat->sprstat_abandoned_sent = stcb->asoc.strmout[sid].abandoned_sent[policy]; + } + SCTP_TCB_UNLOCK(stcb); + *optsize = sizeof(struct sctp_prstatus); + } else { + SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); + error = EINVAL; + } + break; + } + case SCTP_PR_ASSOC_STATUS: + { + struct sctp_prstatus *sprstat; + uint16_t policy; + + SCTP_CHECK_AND_CAST(sprstat, optval, struct sctp_prstatus, *optsize); + SCTP_FIND_STCB(inp, stcb, sprstat->sprstat_assoc_id); + + policy = sprstat->sprstat_policy; + if ((stcb != NULL) && + (policy != SCTP_PR_SCTP_NONE) && + ((policy == SCTP_PR_SCTP_ALL) || + (PR_SCTP_VALID_POLICY(policy)))) { + if (policy == SCTP_PR_SCTP_ALL) { + sprstat->sprstat_abandoned_unsent = stcb->asoc.abandoned_unsent[0]; + sprstat->sprstat_abandoned_sent = stcb->asoc.abandoned_sent[0]; + } else { + sprstat->sprstat_abandoned_unsent = stcb->asoc.abandoned_unsent[policy]; + sprstat->sprstat_abandoned_sent = stcb->asoc.abandoned_sent[policy]; + } + SCTP_TCB_UNLOCK(stcb); + *optsize = sizeof(struct sctp_prstatus); + } else { + SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL); + error = EINVAL; + } + break; + } default: SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT); error = ENOPROTOOPT; diff --git a/netinet/sctputil.c b/netinet/sctputil.c index e240bff..7e0541a 100755 --- a/netinet/sctputil.c +++ b/netinet/sctputil.c @@ -32,7 +32,7 @@ #ifdef __FreeBSD__ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 269858 2014-08-12 11:30:16Z tuexen $"); +__FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 269945 2014-08-13 15:50:16Z tuexen $"); #endif #include <netinet/sctp_os.h> @@ -963,6 +963,9 @@ sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, * caller in the sctp_aloc_assoc() function. */ int i; +#if defined(SCTP_DETAILED_STR_STATS) + int j; +#endif asoc = &stcb->asoc; /* init all variables to a known value. */ @@ -1137,6 +1140,15 @@ sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, asoc->strmout[i].next_sequence_send = 0x0; TAILQ_INIT(&asoc->strmout[i].outqueue); asoc->strmout[i].chunks_on_queues = 0; +#if defined(SCTP_DETAILED_STR_STATS) + for (j = 0; j < SCTP_PR_SCTP_MAX + 1; j++) { + asoc->strmout[i].abandoned_sent[j] = 0; + asoc->strmout[i].abandoned_unsent[j] = 0; + } +#else + asoc->strmout[i].abandoned_sent[0] = 0; + asoc->strmout[i].abandoned_unsent[0] = 0; +#endif asoc->strmout[i].stream_no = i; asoc->strmout[i].last_msg_incomplete = 0; asoc->ss_functions.sctp_ss_init_stream(&asoc->strmout[i], NULL); @@ -1192,6 +1204,10 @@ sctp_init_asoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, asoc->timoshutdownack = 0; (void)SCTP_GETTIME_TIMEVAL(&asoc->start_time); asoc->discontinuity_time = asoc->start_time; + for (i = 0; i < SCTP_PR_SCTP_MAX + 1; i++) { + asoc->abandoned_unsent[i] = 0; + asoc->abandoned_sent[i] = 0; + } /* sa_ignore MEMLEAK {memory is put in the assoc mapping array and freed later when * the association is freed. */ @@ -5162,6 +5178,7 @@ sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1, int ret_sz = 0; int notdone; int do_wakeup_routine = 0; + #if defined(__APPLE__) if (so_locked) { sctp_lock_assert(SCTP_INP_SO(stcb->sctp_ep)); @@ -5171,6 +5188,21 @@ sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1, #endif stream = tp1->rec.data.stream_number; seq = tp1->rec.data.stream_seq; + if (sent || !(tp1->rec.data.rcv_flags & SCTP_DATA_FIRST_FRAG)) { + stcb->asoc.abandoned_sent[0]++; + stcb->asoc.abandoned_sent[PR_SCTP_POLICY(tp1->flags)]++; + stcb->asoc.strmout[stream].abandoned_sent[0]++; +#if defined(SCTP_DETAILED_STR_STATS) + stcb->asoc.strmout[stream].abandoned_sent[PR_SCTP_POLICY(tp1->flags)]++; +#endif + } else { + stcb->asoc.abandoned_unsent[0]++; + stcb->asoc.abandoned_unsent[PR_SCTP_POLICY(tp1->flags)]++; + stcb->asoc.strmout[stream].abandoned_unsent[0]++; +#if defined(SCTP_DETAILED_STR_STATS) + stcb->asoc.strmout[stream].abandoned_unsent[PR_SCTP_POLICY(tp1->flags)]++; +#endif + } do { ret_sz += tp1->book_size; if (tp1->data != NULL) { |