diff options
author | tuexen <tuexen@9df1edf5-d72c-5b5f-11c0-5f5209eb73f7> | 2011-11-13 13:41:49 +0000 |
---|---|---|
committer | tuexen <tuexen@9df1edf5-d72c-5b5f-11c0-5f5209eb73f7> | 2011-11-13 13:41:49 +0000 |
commit | fbf619a4618811e6651f5a78cbacc6530797fd7e (patch) | |
tree | 659ff785253cf81afe7c9f8502f7e2fdc33b9891 /netinet/sctp_indata.c | |
parent | 60416fb97d019e56677da96dbdac6d48048822d3 (diff) | |
download | usrsctplib-fbf619a4618811e6651f5a78cbacc6530797fd7e.tar.gz |
Add callback API stuff.
From Irene.
git-svn-id: http://sctp-refimpl.googlecode.com/svn/trunk/KERN/usrsctp/usrsctplib@7265 9df1edf5-d72c-5b5f-11c0-5f5209eb73f7
Diffstat (limited to 'netinet/sctp_indata.c')
-rwxr-xr-x | netinet/sctp_indata.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/netinet/sctp_indata.c b/netinet/sctp_indata.c index 0ccb6ba..cb4124d 100755 --- a/netinet/sctp_indata.c +++ b/netinet/sctp_indata.c @@ -3787,6 +3787,11 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack, int win_probe_recovered = 0; int j, done_once = 0; int rto_ok=1; +#if defined (CALLBACK_API) + struct socket *so; + uint32_t inqueue_bytes, sb_free_now; + struct sctp_inpcb *inp; +#endif if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_LOG_SACK_ARRIVALS_ENABLE) { sctp_misc_ints(SCTP_SACK_LOG_EXPRESS, cumack, @@ -4001,6 +4006,32 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack, } } +#if defined (CALLBACK_API) + inp = stcb->sctp_ep; + so = stcb->sctp_socket; + + if (so) { + inqueue_bytes = stcb->asoc.total_output_queue_size - (stcb->asoc.chunks_on_out_queue * sizeof(struct sctp_data_chunk)); + sb_free_now = SCTP_SB_LIMIT_SND(so) - (inqueue_bytes + stcb->asoc.sb_send_resv); + + /* check if the amount free in the send socket buffer crossed the threshold */ + if (inp->send_callback && + (((inp->send_sb_threshold > 0) && + (sb_free_now >= inp->send_sb_threshold) && + (stcb->asoc.chunks_on_out_queue <= SCTP_BASE_SYSCTL(sctp_max_chunks_on_queue))) || + (inp->send_sb_threshold == 0))) { + atomic_add_int(&stcb->asoc.refcnt, 1); + SCTP_TCB_UNLOCK(stcb); + inp->send_callback(so, sb_free_now); + SCTP_TCB_LOCK(stcb); + atomic_subtract_int(&stcb->asoc.refcnt, 1); + inqueue_bytes = stcb->asoc.total_output_queue_size - (stcb->asoc.chunks_on_out_queue * sizeof(struct sctp_data_chunk)); + sb_free_now = SCTP_SB_LIMIT_SND(so) - (inqueue_bytes + stcb->asoc.sb_send_resv); + } + } + /* update the amount free in the send socket buffer for next time */ + inp->prev_send_sb_free = sb_free_now; +#else /* sa_ignore NO_NULL_CHK */ if (stcb->sctp_socket) { #if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING) @@ -4034,6 +4065,7 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack, sctp_wakeup_log(stcb, cumack, 1, SCTP_NOWAKE_FROM_SACK); } } +#endif /* JRS - Use the congestion control given in the CC module */ if ((asoc->last_acked_seq != cumack) && (ecne_seen == 0)) { @@ -4338,6 +4370,11 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup, int rto_ok=1; uint8_t reneged_all = 0; uint8_t cmt_dac_flag; +#if defined (CALLBACK_API) + struct socket *so; + uint32_t inqueue_bytes, sb_free_now; + struct sctp_inpcb *inp; +#endif /* * we take any chance we can to service our queues since we cannot * get awoken when the socket is read from :< @@ -4751,6 +4788,29 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup, asoc->total_flight = 0; } +#if defined(CALLBACK_API) + inp = stcb->sctp_ep; + so = stcb->sctp_socket; + if (so) { + inqueue_bytes = stcb->asoc.total_output_queue_size - (stcb->asoc.chunks_on_out_queue * sizeof(struct sctp_data_chunk)); + sb_free_now = SCTP_SB_LIMIT_SND(so) - (inqueue_bytes + stcb->asoc.sb_send_resv); + + /* check if the amount free in the send socket buffer crossed the threshold */ + if (inp->send_callback && + (((inp->send_sb_threshold > 0) && (sb_free_now >= inp->send_sb_threshold)) || + (inp->send_sb_threshold == 0))) { + atomic_add_int(&stcb->asoc.refcnt, 1); + SCTP_TCB_UNLOCK(stcb); + inp->send_callback(so, sb_free_now); + SCTP_TCB_LOCK(stcb); + atomic_subtract_int(&stcb->asoc.refcnt, 1); + inqueue_bytes = stcb->asoc.total_output_queue_size - (stcb->asoc.chunks_on_out_queue * sizeof(struct sctp_data_chunk)); + sb_free_now = SCTP_SB_LIMIT_SND(so) - (inqueue_bytes + stcb->asoc.sb_send_resv); + } + } + /* update the amount free in the send socket buffer for next time */ + inp->prev_send_sb_free = sb_free_now; +#else /* sa_ignore NO_NULL_CHK */ if ((wake_him) && (stcb->sctp_socket)) { #if defined (__APPLE__) || defined(SCTP_SO_LOCK_TESTING) @@ -4783,6 +4843,7 @@ sctp_handle_sack(struct mbuf *m, int offset_seg, int offset_dup, sctp_wakeup_log(stcb, cum_ack, wake_him, SCTP_NOWAKE_FROM_SACK); } } +#endif if (asoc->fast_retran_loss_recovery && accum_moved) { if (SCTP_TSN_GE(asoc->last_acked_seq, asoc->fast_recovery_tsn)) { |