summaryrefslogtreecommitdiffstats
path: root/sys/netinet/sctputil.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet/sctputil.c')
-rw-r--r--sys/netinet/sctputil.c164
1 files changed, 124 insertions, 40 deletions
diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c
index e7e0987..76dfc28 100644
--- a/sys/netinet/sctputil.c
+++ b/sys/netinet/sctputil.c
@@ -71,7 +71,7 @@ sctp_sblog(struct sockbuf *sb,
else
sctp_clog.x.sb.stcb_sbcc = 0;
sctp_clog.x.sb.incr = incr;
- CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
+ SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
SCTP_LOG_EVENT_SB,
from,
sctp_clog.x.misc.log1,
@@ -95,7 +95,7 @@ sctp_log_closing(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int16_t loc)
sctp_clog.x.close.state = 0;
}
sctp_clog.x.close.loc = loc;
- CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
+ SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
SCTP_LOG_EVENT_CLOSE,
0,
sctp_clog.x.misc.log1,
@@ -112,7 +112,7 @@ rto_logging(struct sctp_nets *net, int from)
sctp_clog.x.rto.net = (void *)net;
sctp_clog.x.rto.rtt = net->prev_rtt;
- CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
+ SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
SCTP_LOG_EVENT_RTT,
from,
sctp_clog.x.misc.log1,
@@ -133,7 +133,7 @@ sctp_log_strm_del_alt(struct sctp_tcb *stcb, uint32_t tsn, uint16_t sseq, uint16
sctp_clog.x.strlog.e_tsn = 0;
sctp_clog.x.strlog.e_sseq = 0;
sctp_clog.x.strlog.strm = stream;
- CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
+ SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
SCTP_LOG_EVENT_STRM,
from,
sctp_clog.x.misc.log1,
@@ -153,7 +153,7 @@ sctp_log_nagle_event(struct sctp_tcb *stcb, int action)
sctp_clog.x.nagle.total_in_queue = stcb->asoc.total_output_queue_size;
sctp_clog.x.nagle.count_in_queue = stcb->asoc.chunks_on_out_queue;
sctp_clog.x.nagle.count_in_flight = stcb->asoc.total_flight_count;
- CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
+ SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
SCTP_LOG_EVENT_NAGLE,
action,
sctp_clog.x.misc.log1,
@@ -173,7 +173,7 @@ sctp_log_sack(uint32_t old_cumack, uint32_t cumack, uint32_t tsn, uint16_t gaps,
sctp_clog.x.sack.tsn = tsn;
sctp_clog.x.sack.numGaps = gaps;
sctp_clog.x.sack.numDups = dups;
- CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
+ SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
SCTP_LOG_EVENT_SACK,
from,
sctp_clog.x.misc.log1,
@@ -190,7 +190,7 @@ sctp_log_map(uint32_t map, uint32_t cum, uint32_t high, int from)
sctp_clog.x.map.base = map;
sctp_clog.x.map.cum = cum;
sctp_clog.x.map.high = high;
- CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
+ SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
SCTP_LOG_EVENT_MAP,
from,
sctp_clog.x.misc.log1,
@@ -208,7 +208,7 @@ sctp_log_fr(uint32_t biggest_tsn, uint32_t biggest_new_tsn, uint32_t tsn,
sctp_clog.x.fr.largest_tsn = biggest_tsn;
sctp_clog.x.fr.largest_new_tsn = biggest_new_tsn;
sctp_clog.x.fr.tsn = tsn;
- CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
+ SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
SCTP_LOG_EVENT_FR,
from,
sctp_clog.x.misc.log1,
@@ -235,7 +235,7 @@ sctp_log_mb(struct mbuf *m, int from)
sctp_clog.x.mb.ext = 0;
sctp_clog.x.mb.refcnt = 0;
}
- CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
+ SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
SCTP_LOG_EVENT_MBUF,
from,
sctp_clog.x.misc.log1,
@@ -266,7 +266,7 @@ sctp_log_strm_del(struct sctp_queued_to_read *control, struct sctp_queued_to_rea
sctp_clog.x.strlog.e_tsn = 0;
sctp_clog.x.strlog.e_sseq = 0;
}
- CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
+ SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
SCTP_LOG_EVENT_STRM,
from,
sctp_clog.x.misc.log1,
@@ -302,7 +302,7 @@ sctp_log_cwnd(struct sctp_tcb *stcb, struct sctp_nets *net, int augment, uint8_t
sctp_clog.x.cwnd.meets_pseudo_cumack = stcb->asoc.peers_rwnd;
}
sctp_clog.x.cwnd.cwnd_augment = augment;
- CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
+ SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
SCTP_LOG_EVENT_CWND,
from,
sctp_clog.x.misc.log1,
@@ -346,7 +346,7 @@ sctp_log_lock(struct sctp_inpcb *inp, struct sctp_tcb *stcb, uint8_t from)
sctp_clog.x.lock.sockrcvbuf_lock = SCTP_LOCK_UNKNOWN;
sctp_clog.x.lock.socksndbuf_lock = SCTP_LOCK_UNKNOWN;
}
- CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
+ SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
SCTP_LOG_LOCK_EVENT,
from,
sctp_clog.x.misc.log1,
@@ -373,7 +373,7 @@ sctp_log_maxburst(struct sctp_tcb *stcb, struct sctp_nets *net, int error, int b
sctp_clog.x.cwnd.cnt_in_str = 255;
else
sctp_clog.x.cwnd.cnt_in_str = stcb->asoc.stream_queue_cnt;
- CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
+ SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
SCTP_LOG_EVENT_MAXBURST,
from,
sctp_clog.x.misc.log1,
@@ -392,7 +392,7 @@ sctp_log_rwnd(uint8_t from, uint32_t peers_rwnd, uint32_t snd_size, uint32_t ove
sctp_clog.x.rwnd.send_size = snd_size;
sctp_clog.x.rwnd.overhead = overhead;
sctp_clog.x.rwnd.new_rwnd = 0;
- CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
+ SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
SCTP_LOG_EVENT_RWND,
from,
sctp_clog.x.misc.log1,
@@ -410,7 +410,7 @@ sctp_log_rwnd_set(uint8_t from, uint32_t peers_rwnd, uint32_t flight_size, uint3
sctp_clog.x.rwnd.send_size = flight_size;
sctp_clog.x.rwnd.overhead = overhead;
sctp_clog.x.rwnd.new_rwnd = a_rwndval;
- CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
+ SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
SCTP_LOG_EVENT_RWND,
from,
sctp_clog.x.misc.log1,
@@ -428,7 +428,7 @@ sctp_log_mbcnt(uint8_t from, uint32_t total_oq, uint32_t book, uint32_t total_mb
sctp_clog.x.mbcnt.size_change = book;
sctp_clog.x.mbcnt.total_queue_mb_size = total_mbcnt_q;
sctp_clog.x.mbcnt.mbcnt_change = mbcnt;
- CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
+ SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
SCTP_LOG_EVENT_MBCNT,
from,
sctp_clog.x.misc.log1,
@@ -441,7 +441,7 @@ sctp_log_mbcnt(uint8_t from, uint32_t total_oq, uint32_t book, uint32_t total_mb
void
sctp_misc_ints(uint8_t from, uint32_t a, uint32_t b, uint32_t c, uint32_t d)
{
- CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
+ SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
SCTP_LOG_MISC_EVENT,
from,
a, b, c, d);
@@ -484,7 +484,7 @@ sctp_wakeup_log(struct sctp_tcb *stcb, uint32_t cumtsn, uint32_t wake_cnt, int f
} else {
sctp_clog.x.wake.sbflags = 0xff;
}
- CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
+ SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
SCTP_LOG_EVENT_WAKE,
from,
sctp_clog.x.misc.log1,
@@ -506,7 +506,7 @@ sctp_log_block(uint8_t from, struct socket *so, struct sctp_association *asoc, i
sctp_clog.x.blk.chunks_on_oque = (uint16_t) asoc->chunks_on_out_queue;
sctp_clog.x.blk.flight_size = (uint16_t) (asoc->total_flight / 1024);
sctp_clog.x.blk.sndlen = sendlen;
- CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
+ SCTP_CTR6(KTR_SCTP, "SCTP:%d[%d]:%x-%x-%x-%x",
SCTP_LOG_EVENT_BLOCK,
from,
sctp_clog.x.misc.log1,
@@ -876,7 +876,7 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb,
asoc = &stcb->asoc;
/* init all variables to a known value. */
- asoc->state = SCTP_STATE_INUSE;
+ SCTP_SET_STATE(&stcb->asoc, SCTP_STATE_INUSE);
asoc->max_burst = m->sctp_ep.max_burst;
asoc->heart_beat_delay = TICKS_TO_MSEC(m->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]);
asoc->cookie_life = m->sctp_ep.def_cookie_life;
@@ -902,6 +902,7 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb,
if (sctp_is_vtag_good(m, override_tag, &now)) {
asoc->my_vtag = override_tag;
} else {
+ SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOMEM);
return (ENOMEM);
}
@@ -1095,6 +1096,7 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb,
SCTP_M_STRMO);
if (asoc->strmout == NULL) {
/* big trouble no memory */
+ SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOMEM);
return (ENOMEM);
}
for (i = 0; i < asoc->streamoutcnt; i++) {
@@ -1119,6 +1121,7 @@ sctp_init_asoc(struct sctp_inpcb *m, struct sctp_tcb *stcb,
SCTP_M_MAP);
if (asoc->mapping_array == NULL) {
SCTP_FREE(asoc->strmout, SCTP_M_STRMO);
+ SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOMEM);
return (ENOMEM);
}
memset(asoc->mapping_array, 0, asoc->mapping_array_size);
@@ -1219,8 +1222,6 @@ select_a_new_ep:
SCTP_INP_WLOCK(it->inp);
}
- /* mark the current iterator on the endpoint */
- it->inp->inp_starting_point_for_iterator = it;
SCTP_INP_WUNLOCK(it->inp);
SCTP_INP_RLOCK(it->inp);
@@ -1243,10 +1244,6 @@ select_a_new_ep:
SCTP_INP_RUNLOCK(it->inp);
goto no_stcb;
}
- if ((it->stcb) &&
- (it->stcb->asoc.stcb_starting_point_for_iterator == it)) {
- it->stcb->asoc.stcb_starting_point_for_iterator = NULL;
- }
while (it->stcb) {
SCTP_TCB_LOCK(it->stcb);
if (it->asoc_state && ((it->stcb->asoc.state & it->asoc_state) != it->asoc_state)) {
@@ -1254,18 +1251,20 @@ select_a_new_ep:
SCTP_TCB_UNLOCK(it->stcb);
goto next_assoc;
}
- /* mark the current iterator on the assoc */
- it->stcb->asoc.stcb_starting_point_for_iterator = it;
/* see if we have limited out the iterator loop */
iteration_count++;
if (iteration_count > SCTP_ITERATOR_MAX_AT_ONCE) {
/* Pause to let others grab the lock */
atomic_add_int(&it->stcb->asoc.refcnt, 1);
SCTP_TCB_UNLOCK(it->stcb);
+
+ SCTP_INP_INCR_REF(it->inp);
SCTP_INP_RUNLOCK(it->inp);
SCTP_ITERATOR_UNLOCK();
SCTP_ITERATOR_LOCK();
SCTP_INP_RLOCK(it->inp);
+
+ SCTP_INP_DECR_REF(it->inp);
SCTP_TCB_LOCK(it->stcb);
atomic_add_int(&it->stcb->asoc.refcnt, -1);
iteration_count = 0;
@@ -1297,7 +1296,6 @@ no_stcb:
/* done with all assocs on this endpoint, move on to next endpoint */
it->done_current_ep = 0;
SCTP_INP_WLOCK(it->inp);
- it->inp->inp_starting_point_for_iterator = NULL;
SCTP_INP_WUNLOCK(it->inp);
if (it->iterator_flags & SCTP_ITERATOR_DO_SINGLE_INP) {
it->inp = NULL;
@@ -1582,10 +1580,15 @@ sctp_timeout_handler(void *t)
case SCTP_TIMER_TYPE_RECV:
if ((stcb == NULL) || (inp == NULL)) {
break;
+ } {
+ int abort_flag;
+
+ SCTP_STAT_INCR(sctps_timosack);
+ stcb->asoc.timosack++;
+ if (stcb->asoc.cumulative_tsn != stcb->asoc.highest_tsn_inside_map)
+ sctp_sack_check(stcb, 0, 0, &abort_flag);
+ sctp_send_sack(stcb);
}
- SCTP_STAT_INCR(sctps_timosack);
- stcb->asoc.timosack++;
- sctp_send_sack(stcb);
#ifdef SCTP_AUDITING_ENABLED
sctp_auditing(4, inp, stcb, net);
#endif
@@ -1769,7 +1772,7 @@ sctp_timeout_handler(void *t)
/* Can we free it yet? */
SCTP_INP_DECR_REF(inp);
sctp_timer_stop(SCTP_TIMER_TYPE_ASOCKILL, inp, stcb, NULL, SCTP_FROM_SCTPUTIL + SCTP_LOC_1);
- sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTPUTIL + SCTP_LOC_2);
+ (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTPUTIL + SCTP_LOC_2);
/*
* free asoc, always unlocks (or destroy's) so prevent
* duplicate unlock or unlock of a free mtx :-0
@@ -2176,7 +2179,7 @@ sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb,
tmr->tcb = (void *)stcb;
tmr->net = (void *)net;
tmr->self = (void *)tmr;
- tmr->ticks = ticks;
+ tmr->ticks = sctp_get_tick_count();
(void)SCTP_OS_TIMER_START(&tmr->timer, to_ticks, sctp_timeout_handler, tmr);
return;
}
@@ -2767,6 +2770,7 @@ sctp_add_pad_tombuf(struct mbuf *m, int padlen)
int i;
if (padlen > 3) {
+ SCTP_LTRACE_ERR_RET_PKT(m, NULL, NULL, NULL, SCTP_FROM_SCTPUTIL, ENOBUFS);
return (ENOBUFS);
}
if (M_TRAILINGSPACE(m)) {
@@ -2783,6 +2787,7 @@ sctp_add_pad_tombuf(struct mbuf *m, int padlen)
tmp = sctp_get_mbuf_for_msg(padlen, 0, M_DONTWAIT, 1, MT_DATA);
if (tmp == NULL) {
/* Out of space GAK! we are in big trouble. */
+ SCTP_LTRACE_ERR_RET_PKT(m, NULL, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
return (ENOSPC);
}
/* setup and insert in middle */
@@ -2816,6 +2821,7 @@ sctp_pad_lastmbuf(struct mbuf *m, int padval, struct mbuf *last_mbuf)
m_at = SCTP_BUF_NEXT(m_at);
}
}
+ SCTP_LTRACE_ERR_RET_PKT(m, NULL, NULL, NULL, SCTP_FROM_SCTPUTIL, EFAULT);
return (EFAULT);
}
@@ -2849,10 +2855,13 @@ sctp_notify_assoc_change(uint32_t event, struct sctp_tcb *stcb,
if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
(stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) &&
((event == SCTP_COMM_LOST) || (event == SCTP_CANT_STR_ASSOC))) {
- if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_WAIT)
+ if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_WAIT) {
+ SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ECONNREFUSED);
stcb->sctp_socket->so_error = ECONNREFUSED;
- else
+ } else {
+ SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ECONNRESET);
stcb->sctp_socket->so_error = ECONNRESET;
+ }
/* Wake ANY sleepers */
sorwakeup(stcb->sctp_socket);
sowwakeup(stcb->sctp_socket);
@@ -3658,7 +3667,7 @@ sctp_abort_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
sctp_send_abort(m, iphlen, sh, vtag, op_err, vrf_id);
if (stcb != NULL) {
/* Ok, now lets free it */
- sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTPUTIL + SCTP_LOC_4);
+ (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTPUTIL + SCTP_LOC_4);
} else {
if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) {
if (LIST_FIRST(&inp->sctp_asoc_list) == NULL) {
@@ -3766,7 +3775,7 @@ sctp_abort_an_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
#ifdef SCTP_ASOCLOG_OF_TSNS
sctp_print_out_track_log(stcb);
#endif
- sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTPUTIL + SCTP_LOC_5);
+ (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTPUTIL + SCTP_LOC_5);
}
void
@@ -4687,6 +4696,7 @@ sctp_sorecvmsg(struct socket *so,
int sockbuf_lock = 0;
if (uio == NULL) {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
return (EINVAL);
}
if (msg_flags) {
@@ -4704,6 +4714,7 @@ sctp_sorecvmsg(struct socket *so,
return (EOPNOTSUPP);
}
if ((in_flags & MSG_PEEK) && (mp != NULL)) {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
return (EINVAL);
}
if ((in_flags & (MSG_DONTWAIT
@@ -4715,6 +4726,7 @@ sctp_sorecvmsg(struct socket *so,
/* setup the endpoint */
inp = (struct sctp_inpcb *)so->so_pcb;
if (inp == NULL) {
+ SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTPUTIL, EFAULT);
return (EFAULT);
}
rwnd_req = (SCTP_SB_LIMIT_RCV(so) >> SCTP_RWND_HIWAT_SHIFT);
@@ -4753,6 +4765,7 @@ restart_nosblocks:
if ((in_flags & MSG_PEEK) == 0)
so->so_error = 0;
} else {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, ENOTCONN);
error = ENOTCONN;
}
goto out;
@@ -4773,6 +4786,7 @@ restart_nosblocks:
* You were aborted, passive side
* always hits here
*/
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, ECONNRESET);
error = ECONNRESET;
/*
* You get this once if you are
@@ -4792,6 +4806,7 @@ restart_nosblocks:
SS_ISCONNECTED);
if (error == 0) {
if ((inp->sctp_flags & SCTP_PCB_FLAGS_WAS_CONNECTED) == 0) {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, ENOTCONN);
error = ENOTCONN;
} else {
inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAS_CONNECTED;
@@ -4825,6 +4840,7 @@ restart_nosblocks:
* You were aborted, passive
* side always hits here
*/
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, ECONNRESET);
error = ECONNRESET;
/*
* You get this once if you
@@ -4845,6 +4861,7 @@ restart_nosblocks:
SS_ISCONNECTED);
if (error == 0) {
if ((inp->sctp_flags & SCTP_PCB_FLAGS_WAS_CONNECTED) == 0) {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, ENOTCONN);
error = ENOTCONN;
} else {
inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAS_CONNECTED;
@@ -4853,6 +4870,7 @@ restart_nosblocks:
goto out;
}
}
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EWOULDBLOCK);
error = EWOULDBLOCK;
}
goto out;
@@ -5216,6 +5234,7 @@ get_more_data:
embuf = m;
copied_so_far += cp_len;
freed_so_far += cp_len;
+ freed_so_far += MSIZE;
atomic_subtract_int(&control->length, cp_len);
control->data = sctp_m_free(m);
m = control->data;
@@ -5266,6 +5285,7 @@ get_more_data:
copied_so_far += cp_len;
embuf = m;
freed_so_far += cp_len;
+ freed_so_far += MSIZE;
if (sctp_logging_level & SCTP_SB_LOGGING_ENABLE) {
sctp_sblog(&so->so_rcv, control->do_not_ref_stcb ? NULL : stcb,
SCTP_LOG_SBRESULT, 0);
@@ -5483,6 +5503,7 @@ wait_some_more:
}
sctp_sbfree(control, stcb, &so->so_rcv, m);
freed_so_far += SCTP_BUF_LEN(m);
+ freed_so_far += MSIZE;
if (sctp_logging_level & SCTP_SB_LOGGING_ENABLE) {
sctp_sblog(&so->so_rcv,
control->do_not_ref_stcb ? NULL : stcb, SCTP_LOG_SBRESULT, 0);
@@ -5612,6 +5633,7 @@ sctp_dynamic_set_primary(struct sockaddr *sa, uint32_t vrf_id)
ifa = sctp_find_ifa_by_addr(sa, vrf_id, 0);
if (ifa == NULL) {
+ SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTPUTIL, EADDRNOTAVAIL);
return (EADDRNOTAVAIL);
}
/*
@@ -5620,6 +5642,7 @@ sctp_dynamic_set_primary(struct sockaddr *sa, uint32_t vrf_id)
*/
wi = SCTP_ZONE_GET(sctppcbinfo.ipi_zone_laddr, struct sctp_laddr);
if (wi == NULL) {
+ SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTPUTIL, ENOMEM);
return (ENOMEM);
}
/* Now incr the count and int wi structure */
@@ -5666,6 +5689,7 @@ sctp_soreceive(struct socket *so,
inp = (struct sctp_inpcb *)so->so_pcb;
/* pickup the assoc we are reading from */
if (inp == NULL) {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
return (EINVAL);
}
if ((sctp_is_feature_off(inp,
@@ -5723,6 +5747,7 @@ sctp_l_soreceive(struct socket *so,
inp = (struct sctp_inpcb *)so->so_pcb;
/* pickup the assoc we are reading from */
if (inp == NULL) {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
return (EINVAL);
}
if ((sctp_is_feature_off(inp,
@@ -5790,7 +5815,8 @@ sctp_connectx_helper_add(struct sctp_tcb *stcb, struct sockaddr *addr,
incr = sizeof(struct sockaddr_in);
if (sctp_add_remote_addr(stcb, sa, SCTP_DONOT_SETSCOPE, SCTP_ADDR_IS_CONFIRMED)) {
/* assoc gone no un-lock */
- sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_7);
+ SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOBUFS);
+ (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_7);
*error = ENOBUFS;
goto out_now;
}
@@ -5799,7 +5825,8 @@ sctp_connectx_helper_add(struct sctp_tcb *stcb, struct sockaddr *addr,
incr = sizeof(struct sockaddr_in6);
if (sctp_add_remote_addr(stcb, sa, SCTP_DONOT_SETSCOPE, SCTP_ADDR_IS_CONFIRMED)) {
/* assoc gone no un-lock */
- sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_8);
+ SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, SCTP_FROM_SCTPUTIL, ENOBUFS);
+ (void)sctp_free_assoc(inp, stcb, SCTP_NORMAL_PROC, SCTP_FROM_SCTP_USRREQ + SCTP_LOC_8);
*error = ENOBUFS;
goto out_now;
}
@@ -5829,6 +5856,7 @@ sctp_connectx_helper_find(struct sctp_inpcb *inp, struct sockaddr *addr,
(*num_v4) += 1;
incr = sizeof(struct sockaddr_in);
if (sa->sa_len != incr) {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
*error = EINVAL;
*bad_addr = 1;
return (NULL);
@@ -5839,6 +5867,7 @@ sctp_connectx_helper_find(struct sctp_inpcb *inp, struct sockaddr *addr,
sin6 = (struct sockaddr_in6 *)sa;
if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
/* Must be non-mapped for connectx */
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
*error = EINVAL;
*bad_addr = 1;
return (NULL);
@@ -5846,6 +5875,7 @@ sctp_connectx_helper_find(struct sctp_inpcb *inp, struct sockaddr *addr,
(*num_v6) += 1;
incr = sizeof(struct sockaddr_in6);
if (sa->sa_len != incr) {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
*error = EINVAL;
*bad_addr = 1;
return (NULL);
@@ -5886,6 +5916,7 @@ sctp_bindx_add_address(struct socket *so, struct sctp_inpcb *inp,
/* see if we're bound all already! */
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
*error = EINVAL;
return;
}
@@ -5895,11 +5926,13 @@ sctp_bindx_add_address(struct socket *so, struct sctp_inpcb *inp,
struct sockaddr_in6 *sin6;
if (sa->sa_len != sizeof(struct sockaddr_in6)) {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
*error = EINVAL;
return;
}
if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
/* can only bind v6 on PF_INET6 sockets */
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
*error = EINVAL;
return;
}
@@ -5908,6 +5941,7 @@ sctp_bindx_add_address(struct socket *so, struct sctp_inpcb *inp,
if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
SCTP_IPV6_V6ONLY(inp)) {
/* can't bind v4-mapped on PF_INET sockets */
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
*error = EINVAL;
return;
}
@@ -5918,12 +5952,14 @@ sctp_bindx_add_address(struct socket *so, struct sctp_inpcb *inp,
#endif
if (sa->sa_family == AF_INET) {
if (sa->sa_len != sizeof(struct sockaddr_in)) {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
*error = EINVAL;
return;
}
if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
SCTP_IPV6_V6ONLY(inp)) {
/* can't bind v4 on PF_INET sockets */
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
*error = EINVAL;
return;
}
@@ -5931,6 +5967,7 @@ sctp_bindx_add_address(struct socket *so, struct sctp_inpcb *inp,
if (inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) {
if (p == NULL) {
/* Can't get proc for Net/Open BSD */
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
*error = EINVAL;
return;
}
@@ -5950,6 +5987,7 @@ sctp_bindx_add_address(struct socket *so, struct sctp_inpcb *inp,
/* validate the incoming port */
if ((lsin->sin_port != 0) &&
(lsin->sin_port != inp->sctp_lport)) {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
*error = EINVAL;
return;
} else {
@@ -6000,6 +6038,7 @@ sctp_bindx_delete_address(struct socket *so, struct sctp_inpcb *inp,
/* see if we're bound all already! */
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
*error = EINVAL;
return;
}
@@ -6009,11 +6048,13 @@ sctp_bindx_delete_address(struct socket *so, struct sctp_inpcb *inp,
struct sockaddr_in6 *sin6;
if (sa->sa_len != sizeof(struct sockaddr_in6)) {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
*error = EINVAL;
return;
}
if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
/* can only bind v6 on PF_INET6 sockets */
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
*error = EINVAL;
return;
}
@@ -6022,6 +6063,7 @@ sctp_bindx_delete_address(struct socket *so, struct sctp_inpcb *inp,
if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
SCTP_IPV6_V6ONLY(inp)) {
/* can't bind mapped-v4 on PF_INET sockets */
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
*error = EINVAL;
return;
}
@@ -6032,12 +6074,14 @@ sctp_bindx_delete_address(struct socket *so, struct sctp_inpcb *inp,
#endif
if (sa->sa_family == AF_INET) {
if (sa->sa_len != sizeof(struct sockaddr_in)) {
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
*error = EINVAL;
return;
}
if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
SCTP_IPV6_V6ONLY(inp)) {
/* can't bind v4 on PF_INET sockets */
+ SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTPUTIL, EINVAL);
*error = EINVAL;
return;
}
@@ -6168,3 +6212,43 @@ sctp_local_addr_count(struct sctp_tcb *stcb)
}
return (count);
}
+
+#if defined(SCTP_LOCAL_TRACE_BUF)
+
+struct sctp_dump_log {
+ u_int64_t timestamp;
+ const char *descr;
+ uint32_t subsys;
+ uint32_t params[SCTP_TRACE_PARAMS];
+};
+int sctp_log_index = 0;
+struct sctp_dump_log sctp_log[SCTP_MAX_LOGGING_SIZE];
+
+void
+sctp_log_trace(uint32_t subsys, const char *str, uint32_t a, uint32_t b, uint32_t c, uint32_t d, uint32_t e, uint32_t f)
+{
+ int saveindex, newindex;
+
+ do {
+ saveindex = sctp_log_index;
+ if (saveindex >= SCTP_MAX_LOGGING_SIZE) {
+ newindex = 1;
+ } else {
+ newindex = saveindex + 1;
+ }
+ } while (atomic_cmpset_int(&sctp_log_index, saveindex, newindex) == 0);
+ if (saveindex >= SCTP_MAX_LOGGING_SIZE) {
+ saveindex = 0;
+ }
+ sctp_log[saveindex].timestamp = SCTP_GET_CYCLECOUNT;
+ sctp_log[saveindex].subsys = subsys;
+ sctp_log[saveindex].descr = str;
+ sctp_log[saveindex].params[0] = a;
+ sctp_log[saveindex].params[1] = b;
+ sctp_log[saveindex].params[2] = c;
+ sctp_log[saveindex].params[3] = d;
+ sctp_log[saveindex].params[4] = e;
+ sctp_log[saveindex].params[5] = f;
+}
+
+#endif
OpenPOWER on IntegriCloud