summaryrefslogtreecommitdiff
path: root/netinet/sctp_indata.c
diff options
context:
space:
mode:
authortuexen <tuexen@9df1edf5-d72c-5b5f-11c0-5f5209eb73f7>2011-11-13 13:41:49 +0000
committertuexen <tuexen@9df1edf5-d72c-5b5f-11c0-5f5209eb73f7>2011-11-13 13:41:49 +0000
commitfbf619a4618811e6651f5a78cbacc6530797fd7e (patch)
tree659ff785253cf81afe7c9f8502f7e2fdc33b9891 /netinet/sctp_indata.c
parent60416fb97d019e56677da96dbdac6d48048822d3 (diff)
downloadusrsctplib-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-xnetinet/sctp_indata.c61
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)) {