Provide in the SCTP_SEND_FAILED and SCTP_SEND_FAILED_EVENT notifications

the correct ssf_error or ssfe_error as required by RFC 6458.

MFC after: 3 days
This commit is contained in:
tuexen 2012-05-13 19:32:49 +00:00
parent 442f3db615
commit ac46646680
8 changed files with 80 additions and 89 deletions

View File

@ -460,18 +460,6 @@ __FBSDID("$FreeBSD$");
#define SCTP_HAS_NAT_SUPPORT 0xc007
#define SCTP_NAT_VTAGS 0xc008
/* Notification error codes */
#define SCTP_NOTIFY_DATAGRAM_UNSENT 0x0001
#define SCTP_NOTIFY_DATAGRAM_SENT 0x0002
#define SCTP_FAILED_THRESHOLD 0x0004
#define SCTP_HEARTBEAT_SUCCESS 0x0008
#define SCTP_RESPONSE_TO_USER_REQ 0x0010
#define SCTP_INTERNAL_ERROR 0x0020
#define SCTP_SHUTDOWN_GUARD_EXPIRES 0x0040
#define SCTP_RECEIVED_SACK 0x0080
#define SCTP_PEER_FAULTY 0x0100
#define SCTP_ICMP_REFUSED 0x0200
/* bits for TOS field */
#define SCTP_ECT0_BIT 0x02
#define SCTP_ECT1_BIT 0x01
@ -755,27 +743,28 @@ __FBSDID("$FreeBSD$");
#define SCTP_NOTIFY_ASSOC_DOWN 2
#define SCTP_NOTIFY_INTERFACE_DOWN 3
#define SCTP_NOTIFY_INTERFACE_UP 4
#define SCTP_NOTIFY_DG_FAIL 5
#define SCTP_NOTIFY_SPECIAL_SP_FAIL 6
#define SCTP_NOTIFY_ASSOC_LOC_ABORTED 7
#define SCTP_NOTIFY_ASSOC_REM_ABORTED 8
#define SCTP_NOTIFY_ASSOC_RESTART 9
#define SCTP_NOTIFY_PEER_SHUTDOWN 10
#define SCTP_NOTIFY_ASCONF_ADD_IP 11
#define SCTP_NOTIFY_ASCONF_DELETE_IP 12
#define SCTP_NOTIFY_ASCONF_SET_PRIMARY 13
#define SCTP_NOTIFY_PARTIAL_DELVIERY_INDICATION 14
#define SCTP_NOTIFY_INTERFACE_CONFIRMED 15
#define SCTP_NOTIFY_STR_RESET_RECV 16
#define SCTP_NOTIFY_STR_RESET_SEND 17
#define SCTP_NOTIFY_STR_RESET_FAILED_OUT 18
#define SCTP_NOTIFY_STR_RESET_FAILED_IN 19
#define SCTP_NOTIFY_STR_RESET_DENIED_OUT 20
#define SCTP_NOTIFY_STR_RESET_DENIED_IN 21
#define SCTP_NOTIFY_AUTH_NEW_KEY 22
#define SCTP_NOTIFY_AUTH_FREE_KEY 23
#define SCTP_NOTIFY_NO_PEER_AUTH 24
#define SCTP_NOTIFY_SENDER_DRY 25
#define SCTP_NOTIFY_SENT_DG_FAIL 5
#define SCTP_NOTIFY_UNSENT_DG_FAIL 6
#define SCTP_NOTIFY_SPECIAL_SP_FAIL 7
#define SCTP_NOTIFY_ASSOC_LOC_ABORTED 8
#define SCTP_NOTIFY_ASSOC_REM_ABORTED 9
#define SCTP_NOTIFY_ASSOC_RESTART 10
#define SCTP_NOTIFY_PEER_SHUTDOWN 11
#define SCTP_NOTIFY_ASCONF_ADD_IP 12
#define SCTP_NOTIFY_ASCONF_DELETE_IP 13
#define SCTP_NOTIFY_ASCONF_SET_PRIMARY 14
#define SCTP_NOTIFY_PARTIAL_DELVIERY_INDICATION 15
#define SCTP_NOTIFY_INTERFACE_CONFIRMED 16
#define SCTP_NOTIFY_STR_RESET_RECV 17
#define SCTP_NOTIFY_STR_RESET_SEND 18
#define SCTP_NOTIFY_STR_RESET_FAILED_OUT 19
#define SCTP_NOTIFY_STR_RESET_FAILED_IN 20
#define SCTP_NOTIFY_STR_RESET_DENIED_OUT 21
#define SCTP_NOTIFY_STR_RESET_DENIED_IN 22
#define SCTP_NOTIFY_AUTH_NEW_KEY 23
#define SCTP_NOTIFY_AUTH_FREE_KEY 24
#define SCTP_NOTIFY_NO_PEER_AUTH 25
#define SCTP_NOTIFY_SENDER_DRY 26
/* This is the value for messages that are NOT completely
* copied down where we will start to split the message.

View File

@ -3194,8 +3194,7 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
if (timevalcmp(&now, &tp1->rec.data.timetodrop, >)) {
/* Yes so drop it */
if (tp1->data != NULL) {
(void)sctp_release_pr_sctp_chunk(stcb, tp1,
(SCTP_RESPONSE_TO_USER_REQ | SCTP_NOTIFY_DATAGRAM_SENT),
(void)sctp_release_pr_sctp_chunk(stcb, tp1, 1,
SCTP_SO_NOT_LOCKED);
}
continue;
@ -3452,8 +3451,7 @@ sctp_strike_gap_ack_chunks(struct sctp_tcb *stcb, struct sctp_association *asoc,
if (tp1->snd_count > tp1->rec.data.timetodrop.tv_sec) {
/* Yes, so drop it */
if (tp1->data != NULL) {
(void)sctp_release_pr_sctp_chunk(stcb, tp1,
(SCTP_RESPONSE_TO_USER_REQ | SCTP_NOTIFY_DATAGRAM_SENT),
(void)sctp_release_pr_sctp_chunk(stcb, tp1, 1,
SCTP_SO_NOT_LOCKED);
}
/* Make sure to flag we had a FR */
@ -3632,8 +3630,7 @@ sctp_try_advance_peer_ack_point(struct sctp_tcb *stcb,
/* Yes so drop it */
if (tp1->data) {
(void)sctp_release_pr_sctp_chunk(stcb, tp1,
(SCTP_RESPONSE_TO_USER_REQ | SCTP_NOTIFY_DATAGRAM_SENT),
SCTP_SO_NOT_LOCKED);
1, SCTP_SO_NOT_LOCKED);
}
} else {
/*

View File

@ -300,8 +300,8 @@ sctp_process_init(struct sctp_init_chunk *cp, struct sctp_tcb *stcb)
asoc->send_queue_cnt--;
if (chk->data != NULL) {
sctp_free_bufspace(stcb, asoc, chk, 1);
sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb,
SCTP_NOTIFY_DATAGRAM_UNSENT, chk, SCTP_SO_NOT_LOCKED);
sctp_ulp_notify(SCTP_NOTIFY_UNSENT_DG_FAIL, stcb,
0, chk, SCTP_SO_NOT_LOCKED);
if (chk->data) {
sctp_m_freem(chk->data);
chk->data = NULL;
@ -318,8 +318,7 @@ sctp_process_init(struct sctp_init_chunk *cp, struct sctp_tcb *stcb)
TAILQ_REMOVE(&outs->outqueue, sp, next);
asoc->stream_queue_cnt--;
sctp_ulp_notify(SCTP_NOTIFY_SPECIAL_SP_FAIL,
stcb, SCTP_NOTIFY_DATAGRAM_UNSENT,
sp, SCTP_SO_NOT_LOCKED);
stcb, 0, sp, SCTP_SO_NOT_LOCKED);
if (sp->data) {
sctp_m_freem(sp->data);
sp->data = NULL;
@ -1006,7 +1005,7 @@ sctp_handle_shutdown_ack(struct sctp_shutdown_ack_chunk *cp SCTP_UNUSED,
if (!TAILQ_EMPTY(&asoc->send_queue) ||
!TAILQ_EMPTY(&asoc->sent_queue) ||
!stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, asoc)) {
sctp_report_all_outbound(stcb, 0, SCTP_SO_NOT_LOCKED);
sctp_report_all_outbound(stcb, 0, 0, SCTP_SO_NOT_LOCKED);
}
/* stop the timer */
sctp_timer_stop(SCTP_TIMER_TYPE_SHUTDOWN, stcb->sctp_ep, stcb, net, SCTP_FROM_SCTP_INPUT + SCTP_LOC_9);
@ -1889,7 +1888,7 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
/* send up all the data */
SCTP_TCB_SEND_LOCK(stcb);
sctp_report_all_outbound(stcb, 1, SCTP_SO_NOT_LOCKED);
sctp_report_all_outbound(stcb, 0, 1, SCTP_SO_NOT_LOCKED);
for (i = 0; i < stcb->asoc.streamoutcnt; i++) {
stcb->asoc.strmout[i].stream_no = i;
stcb->asoc.strmout[i].next_sequence_sent = 0;
@ -3176,7 +3175,7 @@ sctp_handle_shutdown_complete(struct sctp_shutdown_complete_chunk *cp SCTP_UNUSE
if (!TAILQ_EMPTY(&asoc->send_queue) ||
!TAILQ_EMPTY(&asoc->sent_queue) ||
!stcb->asoc.ss_functions.sctp_ss_is_empty(stcb, asoc)) {
sctp_report_all_outbound(stcb, 0, SCTP_SO_NOT_LOCKED);
sctp_report_all_outbound(stcb, 0, 0, SCTP_SO_NOT_LOCKED);
}
}
/* stop the timer */

View File

@ -6091,14 +6091,14 @@ sctp_prune_prsctp(struct sctp_tcb *stcb,
* if the mbuf is here
*/
int ret_spc;
int cause;
uint8_t sent;
if (chk->sent > SCTP_DATAGRAM_UNSENT)
cause = SCTP_RESPONSE_TO_USER_REQ | SCTP_NOTIFY_DATAGRAM_SENT;
sent = 1;
else
cause = SCTP_RESPONSE_TO_USER_REQ | SCTP_NOTIFY_DATAGRAM_UNSENT;
sent = 0;
ret_spc = sctp_release_pr_sctp_chunk(stcb, chk,
cause,
sent,
SCTP_SO_LOCKED);
freed_spc += ret_spc;
if (freed_spc >= dataout) {
@ -6121,8 +6121,7 @@ sctp_prune_prsctp(struct sctp_tcb *stcb,
int ret_spc;
ret_spc = sctp_release_pr_sctp_chunk(stcb, chk,
SCTP_RESPONSE_TO_USER_REQ | SCTP_NOTIFY_DATAGRAM_UNSENT,
SCTP_SO_LOCKED);
0, SCTP_SO_LOCKED);
freed_spc += ret_spc;
if (freed_spc >= dataout) {

View File

@ -4990,8 +4990,7 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
if (so) {
/* Still an open socket - report */
sctp_ulp_notify(SCTP_NOTIFY_SPECIAL_SP_FAIL, stcb,
SCTP_NOTIFY_DATAGRAM_UNSENT,
(void *)sp, SCTP_SO_LOCKED);
0, (void *)sp, SCTP_SO_LOCKED);
}
if (sp->data) {
sctp_m_freem(sp->data);
@ -5051,8 +5050,8 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
if (chk->data) {
if (so) {
/* Still a socket? */
sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb,
SCTP_NOTIFY_DATAGRAM_UNSENT, chk, SCTP_SO_LOCKED);
sctp_ulp_notify(SCTP_NOTIFY_UNSENT_DG_FAIL, stcb,
0, chk, SCTP_SO_LOCKED);
}
if (chk->data) {
sctp_m_freem(chk->data);
@ -5075,8 +5074,8 @@ sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfre
if (chk->data) {
if (so) {
/* Still a socket? */
sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb,
SCTP_NOTIFY_DATAGRAM_SENT, chk, SCTP_SO_LOCKED);
sctp_ulp_notify(SCTP_NOTIFY_SENT_DG_FAIL, stcb,
0, chk, SCTP_SO_LOCKED);
}
if (chk->data) {
sctp_m_freem(chk->data);

View File

@ -614,7 +614,7 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
if (chk->data) {
(void)sctp_release_pr_sctp_chunk(stcb,
chk,
(SCTP_RESPONSE_TO_USER_REQ | SCTP_NOTIFY_DATAGRAM_SENT),
1,
SCTP_SO_NOT_LOCKED);
cnt_abandoned++;
}
@ -627,7 +627,7 @@ sctp_mark_all_for_resend(struct sctp_tcb *stcb,
if (chk->data) {
(void)sctp_release_pr_sctp_chunk(stcb,
chk,
(SCTP_RESPONSE_TO_USER_REQ | SCTP_NOTIFY_DATAGRAM_SENT),
1,
SCTP_SO_NOT_LOCKED);
cnt_abandoned++;
}

View File

@ -2810,7 +2810,7 @@ sctp_notify_peer_addr_change(struct sctp_tcb *stcb, uint32_t state,
static void
sctp_notify_send_failed(struct sctp_tcb *stcb, uint32_t error,
sctp_notify_send_failed(struct sctp_tcb *stcb, uint8_t sent, uint32_t error,
struct sctp_tmit_chunk *chk, int so_locked
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
SCTP_UNUSED
@ -2844,10 +2844,11 @@ sctp_notify_send_failed(struct sctp_tcb *stcb, uint32_t error,
if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) {
ssfe = mtod(m_notify, struct sctp_send_failed_event *);
ssfe->ssfe_type = SCTP_SEND_FAILED_EVENT;
if (error == SCTP_NOTIFY_DATAGRAM_UNSENT)
ssfe->ssfe_flags = SCTP_DATA_UNSENT;
else
if (sent) {
ssfe->ssfe_flags = SCTP_DATA_SENT;
} else {
ssfe->ssfe_flags = SCTP_DATA_UNSENT;
}
ssfe->ssfe_length = length;
ssfe->ssfe_error = error;
/* not exactly what the user sent in, but should be close :) */
@ -2862,10 +2863,11 @@ sctp_notify_send_failed(struct sctp_tcb *stcb, uint32_t error,
} else {
ssf = mtod(m_notify, struct sctp_send_failed *);
ssf->ssf_type = SCTP_SEND_FAILED;
if (error == SCTP_NOTIFY_DATAGRAM_UNSENT)
ssf->ssf_flags = SCTP_DATA_UNSENT;
else
if (sent) {
ssf->ssf_flags = SCTP_DATA_SENT;
} else {
ssf->ssf_flags = SCTP_DATA_UNSENT;
}
ssf->ssf_length = length;
ssf->ssf_error = error;
/* not exactly what the user sent in, but should be close :) */
@ -2954,10 +2956,7 @@ sctp_notify_send_failed2(struct sctp_tcb *stcb, uint32_t error,
if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) {
ssfe = mtod(m_notify, struct sctp_send_failed_event *);
ssfe->ssfe_type = SCTP_SEND_FAILED;
if (error == SCTP_NOTIFY_DATAGRAM_UNSENT)
ssfe->ssfe_flags = SCTP_DATA_UNSENT;
else
ssfe->ssfe_flags = SCTP_DATA_SENT;
ssfe->ssfe_flags = SCTP_DATA_UNSENT;
ssfe->ssfe_length = length;
ssfe->ssfe_error = error;
/* not exactly what the user sent in, but should be close :) */
@ -2976,10 +2975,7 @@ sctp_notify_send_failed2(struct sctp_tcb *stcb, uint32_t error,
} else {
ssf = mtod(m_notify, struct sctp_send_failed *);
ssf->ssf_type = SCTP_SEND_FAILED;
if (error == SCTP_NOTIFY_DATAGRAM_UNSENT)
ssf->ssf_flags = SCTP_DATA_UNSENT;
else
ssf->ssf_flags = SCTP_DATA_SENT;
ssf->ssf_flags = SCTP_DATA_UNSENT;
ssf->ssf_length = length;
ssf->ssf_error = error;
/* not exactly what the user sent in, but should be close :) */
@ -3543,8 +3539,12 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
sctp_notify_send_failed2(stcb, error,
(struct sctp_stream_queue_pending *)data, so_locked);
break;
case SCTP_NOTIFY_DG_FAIL:
sctp_notify_send_failed(stcb, error,
case SCTP_NOTIFY_SENT_DG_FAIL:
sctp_notify_send_failed(stcb, 1, error,
(struct sctp_tmit_chunk *)data, so_locked);
break;
case SCTP_NOTIFY_UNSENT_DG_FAIL:
sctp_notify_send_failed(stcb, 0, error,
(struct sctp_tmit_chunk *)data, so_locked);
break;
case SCTP_NOTIFY_PARTIAL_DELVIERY_INDICATION:
@ -3642,7 +3642,7 @@ sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb,
}
void
sctp_report_all_outbound(struct sctp_tcb *stcb, int holds_lock, int so_locked
sctp_report_all_outbound(struct sctp_tcb *stcb, uint16_t error, int holds_lock, int so_locked
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
SCTP_UNUSED
#endif
@ -3677,8 +3677,8 @@ sctp_report_all_outbound(struct sctp_tcb *stcb, int holds_lock, int so_locked
asoc->sent_queue_cnt--;
if (chk->data != NULL) {
sctp_free_bufspace(stcb, asoc, chk, 1);
sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb,
SCTP_NOTIFY_DATAGRAM_SENT, chk, so_locked);
sctp_ulp_notify(SCTP_NOTIFY_SENT_DG_FAIL, stcb,
error, chk, so_locked);
if (chk->data) {
sctp_m_freem(chk->data);
chk->data = NULL;
@ -3693,8 +3693,8 @@ sctp_report_all_outbound(struct sctp_tcb *stcb, int holds_lock, int so_locked
asoc->send_queue_cnt--;
if (chk->data != NULL) {
sctp_free_bufspace(stcb, asoc, chk, 1);
sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb,
SCTP_NOTIFY_DATAGRAM_UNSENT, chk, so_locked);
sctp_ulp_notify(SCTP_NOTIFY_UNSENT_DG_FAIL, stcb,
error, chk, so_locked);
if (chk->data) {
sctp_m_freem(chk->data);
chk->data = NULL;
@ -3714,7 +3714,7 @@ sctp_report_all_outbound(struct sctp_tcb *stcb, int holds_lock, int so_locked
sctp_free_spbufspace(stcb, asoc, sp);
if (sp->data) {
sctp_ulp_notify(SCTP_NOTIFY_SPECIAL_SP_FAIL, stcb,
SCTP_NOTIFY_DATAGRAM_UNSENT, (void *)sp, so_locked);
error, (void *)sp, so_locked);
if (sp->data) {
sctp_m_freem(sp->data);
sp->data = NULL;
@ -3757,7 +3757,7 @@ sctp_abort_notification(struct sctp_tcb *stcb, uint8_t from_peer, uint16_t error
return;
}
/* Tell them we lost the asoc */
sctp_report_all_outbound(stcb, 1, so_locked);
sctp_report_all_outbound(stcb, error, 1, so_locked);
if (from_peer) {
sctp_ulp_notify(SCTP_NOTIFY_ASSOC_REM_ABORTED, stcb, error, abort, so_locked);
} else {
@ -4655,7 +4655,7 @@ sctp_free_bufspace(struct sctp_tcb *stcb, struct sctp_association *asoc,
int
sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1,
int reason, int so_locked
uint8_t sent, int so_locked
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
SCTP_UNUSED
#endif
@ -4682,7 +4682,11 @@ sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1,
sctp_free_bufspace(stcb, &stcb->asoc, tp1, 1);
stcb->asoc.peers_rwnd += tp1->send_size;
stcb->asoc.peers_rwnd += SCTP_BASE_SYSCTL(sctp_peer_chunk_oh);
sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb, reason, tp1, so_locked);
if (sent) {
sctp_ulp_notify(SCTP_NOTIFY_SENT_DG_FAIL, stcb, 0, tp1, so_locked);
} else {
sctp_ulp_notify(SCTP_NOTIFY_UNSENT_DG_FAIL, stcb, 0, tp1, so_locked);
}
if (tp1->data) {
sctp_m_freem(tp1->data);
tp1->data = NULL;
@ -4729,7 +4733,11 @@ sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1,
chk = tp1;
ret_sz += tp1->book_size;
sctp_free_bufspace(stcb, &stcb->asoc, tp1, 1);
sctp_ulp_notify(SCTP_NOTIFY_DG_FAIL, stcb, reason, tp1, so_locked);
if (sent) {
sctp_ulp_notify(SCTP_NOTIFY_SENT_DG_FAIL, stcb, 0, tp1, so_locked);
} else {
sctp_ulp_notify(SCTP_NOTIFY_UNSENT_DG_FAIL, stcb, 0, tp1, so_locked);
}
if (tp1->data) {
sctp_m_freem(tp1->data);
tp1->data = NULL;

View File

@ -170,7 +170,7 @@ sctp_pull_off_control_to_new_inp(struct sctp_inpcb *old_inp,
void sctp_stop_timers_for_shutdown(struct sctp_tcb *);
void
sctp_report_all_outbound(struct sctp_tcb *, int, int
sctp_report_all_outbound(struct sctp_tcb *, uint16_t, int, int
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
SCTP_UNUSED
#endif
@ -244,7 +244,7 @@ void sctp_print_address_pkt(struct ip *, struct sctphdr *);
int
sctp_release_pr_sctp_chunk(struct sctp_tcb *, struct sctp_tmit_chunk *,
int, int
uint8_t, int
#if !defined(__APPLE__) && !defined(SCTP_SO_LOCK_TESTING)
SCTP_UNUSED
#endif