- errno -> becomes error in sctp_output.c and sctputil.c

- SB_CLEAR macro defined and used for sb clearing.
- Fix for CMT express_sack_handling did not do proper
  pseudo-cumack updates.
- Get rid of extraneous function that was never used ip_2_ip6_hdr()
- Fixed source address selection bug (initialization problem).
- Source address selection debug added.
This commit is contained in:
Randall Stewart 2007-03-19 06:53:02 +00:00
parent 09dce7a13d
commit 132dea7d5a
9 changed files with 155 additions and 99 deletions

View File

@ -4072,6 +4072,13 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
net->prev_cwnd = net->cwnd;
net->net_ack = 0;
net->net_ack2 = 0;
/*
* CMT: Reset CUC and Fast recovery algo variables before
* SACK processing
*/
net->new_pseudo_cumack = 0;
net->will_exit_fast_recovery = 0;
}
if (sctp_strict_sacks) {
uint32_t send_s;
@ -4173,6 +4180,22 @@ sctp_express_handle_sack(struct sctp_tcb *stcb, uint32_t cumack,
tp1->do_rtt = 0;
}
}
/*
* CMT: CUCv2 algorithm. From the
* cumack'd TSNs, for each TSN being
* acked for the first time, set the
* following variables for the
* corresp destination.
* new_pseudo_cumack will trigger a
* cwnd update.
* find_(rtx_)pseudo_cumack will
* trigger search for the next
* expected (rtx-)pseudo-cumack.
*/
tp1->whoTo->new_pseudo_cumack = 1;
tp1->whoTo->find_pseudo_cumack = 1;
tp1->whoTo->find_rtx_pseudo_cumack = 1;
#ifdef SCTP_CWND_LOGGING
sctp_log_cwnd(stcb, tp1->whoTo, tp1->rec.data.TSN_seq, SCTP_CWND_LOG_FROM_SACK);
#endif

View File

@ -249,6 +249,13 @@ typedef struct callout sctp_os_timer_t;
#define SCTP_CLEAR_SO_NBIO(so) ((so)->so_state &= ~SS_NBIO)
/* get the socket type */
#define SCTP_SO_TYPE(so) ((so)->so_type)
/* reserve sb space for a socket */
#define SCTP_SORESERVE(so, send, recv) soreserve(so, send, recv)
/* clear the socket buffer state */
#define SCTP_SB_CLEAR(sb) \
(sb).sb_cc = 0; \
(sb).sb_mb = NULL; \
(sb).sb_mbcnt = 0;
/*
* SCTP AUTH

View File

@ -2187,20 +2187,42 @@ sctp_is_ifa_addr_prefered(struct sctp_ifa *ifa,
if ((dest_is_priv == 0) && (dest_is_loop == 0)) {
dest_is_global = 1;
}
#ifdef SCTP_DEBUG
if (sctp_debug_on & SCTP_DEBUG_OUTPUT2) {
printf("Is destination prefered:");
sctp_print_address(&ifa->address.sa);
}
#endif
/* Ok the address may be ok */
if (fam == AF_INET6) {
/* ok to use deprecated addresses? */
if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
#ifdef SCTP_DEBUG
if (sctp_debug_on & SCTP_DEBUG_OUTPUT3) {
printf("NO:1\n");
}
#endif
return (NULL);
}
if (ifa->src_is_priv) {
if (dest_is_loop) {
#ifdef SCTP_DEBUG
if (sctp_debug_on & SCTP_DEBUG_OUTPUT3) {
printf("NO:2\n");
}
#endif
return (NULL);
}
}
if (ifa->src_is_glob) {
if (dest_is_loop) {
#ifdef SCTP_DEBUG
if (sctp_debug_on & SCTP_DEBUG_OUTPUT3) {
printf("NO:3\n");
}
#endif
return (NULL);
}
}
@ -2210,18 +2232,54 @@ sctp_is_ifa_addr_prefered(struct sctp_ifa *ifa,
* theory be done slicker (it used to be), but this is
* straightforward and easier to validate :-)
*/
#ifdef SCTP_DEBUG
if (sctp_debug_on & SCTP_DEBUG_OUTPUT3) {
printf("src_loop:%d src_priv:%d src_glob:%d\n",
ifa->src_is_loop, ifa->src_is_priv,
ifa->src_is_glob);
printf("dest_loop:%d dest_priv:%d dest_glob:%d\n",
dest_is_loop, dest_is_priv,
dest_is_global);
}
#endif
if ((ifa->src_is_loop) && (dest_is_priv)) {
#ifdef SCTP_DEBUG
if (sctp_debug_on & SCTP_DEBUG_OUTPUT3) {
printf("NO:4\n");
}
#endif
return (NULL);
}
if ((ifa->src_is_glob) && (dest_is_priv)) {
#ifdef SCTP_DEBUG
if (sctp_debug_on & SCTP_DEBUG_OUTPUT3) {
printf("NO:5\n");
}
#endif
return (NULL);
}
if ((ifa->src_is_loop) && (dest_is_global)) {
#ifdef SCTP_DEBUG
if (sctp_debug_on & SCTP_DEBUG_OUTPUT3) {
printf("NO:6\n");
}
#endif
return (NULL);
}
if ((ifa->src_is_priv) && (dest_is_global)) {
#ifdef SCTP_DEBUG
if (sctp_debug_on & SCTP_DEBUG_OUTPUT3) {
printf("NO:7\n");
}
#endif
return (NULL);
}
#ifdef SCTP_DEBUG
if (sctp_debug_on & SCTP_DEBUG_OUTPUT3) {
printf("YES\n");
}
#endif
/* its a prefered address */
return (ifa);
}
@ -2708,7 +2766,7 @@ sctp_choose_boundall(struct sctp_inpcb *inp,
dest_is_loop,
dest_is_priv, fam);
#ifdef SCTP_DEBUG
if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) {
if (sctp_debug_on & SCTP_DEBUG_OUTPUT2) {
printf("Found %d prefered source addresses\n", num_prefered);
}
#endif
@ -2732,7 +2790,7 @@ sctp_choose_boundall(struct sctp_inpcb *inp,
* nth) and 0 is the first one, 1 is the second one etc...
*/
#ifdef SCTP_DEBUG
if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) {
if (sctp_debug_on & SCTP_DEBUG_OUTPUT2) {
printf("cur_addr_num:%d\n", cur_addr_num);
}
#endif
@ -2753,6 +2811,11 @@ sctp_choose_boundall(struct sctp_inpcb *inp,
* prefered fall through to plan_c.
*/
bound_all_plan_b:
#ifdef SCTP_DEBUG
if (sctp_debug_on & SCTP_DEBUG_OUTPUT2) {
printf("Plan B?\n");
}
#endif
LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
if (dest_is_loop == 0 && SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) {
/* wrong base scope */
@ -2764,7 +2827,7 @@ sctp_choose_boundall(struct sctp_inpcb *inp,
num_prefered = sctp_count_num_prefered_boundall(sctp_ifn, stcb, non_asoc_addr_ok,
dest_is_loop, dest_is_priv, fam);
#ifdef SCTP_DEBUG
if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) {
if (sctp_debug_on & SCTP_DEBUG_OUTPUT2) {
printf("Found ifn:%p %d prefered source addresses\n", ifn, num_prefered);
}
#endif
@ -2818,10 +2881,7 @@ sctp_choose_boundall(struct sctp_inpcb *inp,
*/
#ifdef SCTP_DEBUG
if (sctp_debug_on & SCTP_DEBUG_OUTPUT2) {
if (net) {
printf("Plan C no prefered for Dest:");
sctp_print_address(&net->ro._l_addr.sa);
}
printf("Plan C no prefered for Dest, acceptable for?\n");
}
#endif
@ -2850,6 +2910,11 @@ sctp_choose_boundall(struct sctp_inpcb *inp,
* out and see if we can find an acceptable address somewhere
* amongst all interfaces.
*/
#ifdef SCTP_DEBUG
if (sctp_debug_on & SCTP_DEBUG_OUTPUT2) {
printf("Plan C fails plan D?\n");
}
#endif
LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
if (dest_is_loop == 0 && SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) {
/* wrong base scope */
@ -2999,6 +3064,12 @@ sctp_source_address_selection(struct sctp_inpcb *inp,
dest_is_priv = 1;
}
}
#ifdef SCTP_DEBUG
if (sctp_debug_on & SCTP_DEBUG_OUTPUT2) {
printf("Select source for:");
sctp_print_address((struct sockaddr *)to);
}
#endif
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
/*
* When bound to all if the address list is set it is a
@ -10329,7 +10400,7 @@ sctp_copy_it_in(struct sctp_tcb *stcb,
struct sctp_nets *net,
int max_send_len,
int user_marks_eor,
int *errno,
int *error,
int non_blocking)
{
/*
@ -10342,14 +10413,12 @@ sctp_copy_it_in(struct sctp_tcb *stcb,
struct sctp_stream_queue_pending *sp = NULL;
int resv_in_first;
*errno = 0;
/*
* Unless E_EOR mode is on, we must make a send FIT in one call.
*/
*error = 0;
/* Unless E_EOR mode is on, we must make a send FIT in one call. */
if (((user_marks_eor == 0) && non_blocking) &&
(uio->uio_resid > stcb->sctp_socket->so_snd.sb_hiwat)) {
/* It will NEVER fit */
*errno = EMSGSIZE;
*error = EMSGSIZE;
goto out_now;
}
/* Now can we send this? */
@ -10358,12 +10427,12 @@ sctp_copy_it_in(struct sctp_tcb *stcb,
(SCTP_GET_STATE(asoc) == SCTP_STATE_SHUTDOWN_RECEIVED) ||
(asoc->state & SCTP_STATE_SHUTDOWN_PENDING)) {
/* got data while shutting down */
*errno = ECONNRESET;
*error = ECONNRESET;
goto out_now;
}
sp = SCTP_ZONE_GET(sctppcbinfo.ipi_zone_strmoq, struct sctp_stream_queue_pending);
if (sp == NULL) {
*errno = ENOMEM;
*error = ENOMEM;
goto out_now;
}
SCTP_INCR_STRMOQ_COUNT();
@ -10389,8 +10458,8 @@ sctp_copy_it_in(struct sctp_tcb *stcb,
sp->some_taken = 0;
resv_in_first = sizeof(struct sctp_data_chunk);
sp->data = sp->tail_mbuf = NULL;
*errno = sctp_copy_one(sp, uio, resv_in_first);
if (*errno) {
*error = sctp_copy_one(sp, uio, resv_in_first);
if (*error) {
sctp_free_a_strmoq(stcb, sp);
sp->data = NULL;
sp->net = NULL;

View File

@ -292,7 +292,7 @@ sctp_add_addr_to_vrf(uint32_t vrfid, void *ifn, uint32_t ifn_index,
#endif
return (NULL);
}
memset(sctp_ifap, 0, sizeof(sctp_ifap));
memset(sctp_ifap, 0, sizeof(struct sctp_ifa));
sctp_ifap->ifn_p = sctp_ifnp;
atomic_add_int(&sctp_ifnp->refcount, 1);

View File

@ -568,6 +568,5 @@ sctp_initiate_iterator(inp_func inpf,
struct sctp_inpcb *,
uint8_t co_off);
#endif /* _KERNEL */
#endif /* !__sctp_pcb_h__ */

View File

@ -37,6 +37,9 @@ __FBSDID("$FreeBSD$");
#include <netinet/sctp_pcb.h>
#include <netinet/sctp_header.h>
#include <netinet/sctp_var.h>
#if defined(INET6)
#include <netinet6/sctp6_var.h>
#endif
#include <netinet/sctp_sysctl.h>
#include <netinet/sctp_output.h>
#include <netinet/sctp_bsd_addr.h>
@ -96,27 +99,9 @@ sctp_pcbinfo_cleanup(void)
SCTP_HASH_FREE(sctppcbinfo.sctp_restarthash, sctppcbinfo.hashrestartmark);
}
#ifdef INET6
void
ip_2_ip6_hdr(struct ip6_hdr *ip6, struct ip *ip)
{
bzero(ip6, sizeof(*ip6));
ip6->ip6_vfc = IPV6_VERSION;
ip6->ip6_plen = ip->ip_len;
ip6->ip6_nxt = ip->ip_p;
ip6->ip6_hlim = ip->ip_ttl;
ip6->ip6_src.s6_addr32[2] = ip6->ip6_dst.s6_addr32[2] =
IPV6_ADDR_INT32_SMP;
ip6->ip6_src.s6_addr32[3] = ip->ip_src.s_addr;
ip6->ip6_dst.s6_addr32[3] = ip->ip_dst.s_addr;
}
#endif /* INET6 */
static void
sctp_pathmtu_adustment(struct sctp_inpcb *inp,
sctp_pathmtu_adjustment(struct sctp_inpcb *inp,
struct sctp_tcb *stcb,
struct sctp_nets *net,
uint16_t nxtsz)
@ -219,7 +204,7 @@ sctp_notify_mbuf(struct sctp_inpcb *inp,
}
/* now what about the ep? */
if (stcb->asoc.smallest_mtu > nxtsz) {
sctp_pathmtu_adustment(inp, stcb, net, nxtsz);
sctp_pathmtu_adjustment(inp, stcb, net, nxtsz);
}
if (tmr_stopped)
sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, inp, stcb, net);
@ -230,7 +215,7 @@ sctp_notify_mbuf(struct sctp_inpcb *inp,
void
sctp_notify(struct sctp_inpcb *inp,
int errno,
int error,
struct sctphdr *sh,
struct sockaddr *to,
struct sctp_tcb *stcb,
@ -247,11 +232,11 @@ sctp_notify(struct sctp_inpcb *inp,
}
/* FIX ME FIX ME PROTOPT i.e. no SCTP should ALWAYS be an ABORT */
if ((errno == EHOSTUNREACH) || /* Host is not reachable */
(errno == EHOSTDOWN) || /* Host is down */
(errno == ECONNREFUSED) || /* Host refused the connection, (not
if ((error == EHOSTUNREACH) || /* Host is not reachable */
(error == EHOSTDOWN) || /* Host is down */
(error == ECONNREFUSED) || /* Host refused the connection, (not
* an abort?) */
(errno == ENOPROTOOPT) /* SCTP is not present on host */
(error == ENOPROTOOPT) /* SCTP is not present on host */
) {
/*
* Hmm reachablity problems we must examine closely. If its
@ -259,7 +244,7 @@ sctp_notify(struct sctp_inpcb *inp,
* NO protocol at the other end named SCTP. well we consider
* it a OOTB abort.
*/
if ((errno == EHOSTUNREACH) || (errno == EHOSTDOWN)) {
if ((error == EHOSTUNREACH) || (error == EHOSTDOWN)) {
if (net->dest_state & SCTP_ADDR_REACHABLE) {
/* Ok that destination is NOT reachable */
printf("ICMP (thresh %d/%d) takes interface %p down\n",
@ -300,7 +285,7 @@ sctp_notify(struct sctp_inpcb *inp,
sctp_log_lock(inp, stcb, SCTP_LOG_LOCK_SOCK);
#endif
SOCK_LOCK(inp->sctp_socket);
inp->sctp_socket->so_error = errno;
inp->sctp_socket->so_error = error;
sctp_sowwakeup(inp, inp->sctp_socket);
SOCK_UNLOCK(inp->sctp_socket);
}
@ -465,23 +450,16 @@ sctp_abort(struct socket *so)
#endif
sctp_inpcb_free(inp, 1, 0);
SOCK_LOCK(so);
so->so_snd.sb_cc = 0;
so->so_snd.sb_mb = NULL;
so->so_snd.sb_mbcnt = 0;
SCTP_SB_CLEAR(so->so_snd);
/*
* same for the rcv ones, they are only here for the
* accounting/select.
*/
so->so_rcv.sb_cc = 0;
so->so_rcv.sb_mb = NULL;
so->so_rcv.sb_mbcnt = 0;
/*
* Now null out the reference, we are completely detached.
*/
SCTP_SB_CLEAR(so->so_rcv);
/* Now null out the reference, we are completely detached. */
so->so_pcb = NULL;
SOCK_UNLOCK(so);
} else {
flags = inp->sctp_flags;
if ((flags & SCTP_PCB_FLAGS_SOCKET_GONE) == 0) {
@ -506,7 +484,7 @@ sctp_attach(struct socket *so, int proto, struct thread *p)
if (inp != 0) {
return EINVAL;
}
error = soreserve(so, sctp_sendspace, sctp_recvspace);
error = SCTP_SORESERVE(so, sctp_sendspace, sctp_recvspace);
if (error) {
return error;
}
@ -600,20 +578,14 @@ sctp_close(struct socket *so)
* the SCTP association.
*/
SOCK_LOCK(so);
so->so_snd.sb_cc = 0;
so->so_snd.sb_mb = NULL;
so->so_snd.sb_mbcnt = 0;
SCTP_SB_CLEAR(so->so_snd);
/*
* same for the rcv ones, they are only here for the
* accounting/select.
*/
so->so_rcv.sb_cc = 0;
so->so_rcv.sb_mb = NULL;
so->so_rcv.sb_mbcnt = 0;
/*
* Now null out the reference, we are completely detached.
*/
SCTP_SB_CLEAR(so->so_rcv);
/* Now null out the reference, we are completely detached. */
so->so_pcb = NULL;
SOCK_UNLOCK(so);
} else {
@ -1349,7 +1321,9 @@ sctp_do_connect_x(struct socket *so, struct sctp_inpcb *inp, void *optval,
SCTP_INP_WUNLOCK(inp);
}
vrf_id = SCTP_DEFAULT_VRFID;
/* FIX ME: do we want to pass in a vrf on the connect call? */
vrf_id = inp->def_vrf_id;
/* We are GOOD to go */
stcb = sctp_aloc_assoc(inp, sa, 1, &error, 0, vrf_id);
if (stcb == NULL) {
@ -3066,7 +3040,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
if (paddrp->spp_pathmtu > SCTP_DEFAULT_MINSEGMENT) {
net->mtu = paddrp->spp_pathmtu;
if (net->mtu < stcb->asoc.smallest_mtu)
sctp_pathmtu_adustment(inp, stcb, net, net->mtu);
sctp_pathmtu_adjustment(inp, stcb, net, net->mtu);
}
}
if (paddrp->spp_flags & SPP_PMTUD_ENABLE) {
@ -3338,6 +3312,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
}
/* Is the VRF one we have */
addr_touse = addrs->addr;
#if defined(INET6)
if (addrs->addr->sa_family == AF_INET6) {
struct sockaddr_in6 *sin6;
@ -3347,6 +3322,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
addr_touse = (struct sockaddr *)&sin;
}
}
#endif
if (inp->sctp_flags & SCTP_PCB_FLAGS_UNBOUND) {
if (p == NULL) {
/* Can't get proc for Net/Open BSD */
@ -3410,6 +3386,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
break;
}
addr_touse = addrs->addr;
#if defined(INET6)
if (addrs->addr->sa_family == AF_INET6) {
struct sockaddr_in6 *sin6;
@ -3419,6 +3396,7 @@ sctp_setopt(struct socket *so, int optname, void *optval, size_t optsize,
addr_touse = (struct sockaddr *)&sin;
}
}
#endif
/*
* No lock required mgmt_ep_sa does its own locking.
* If the FIX: below is ever changed we may need to
@ -3760,6 +3738,7 @@ sctp_ingetaddr(struct socket *so, struct sockaddr **addr)
struct sockaddr_in *sin;
uint32_t vrf_id;
struct sctp_inpcb *inp;
struct sctp_ifa *sctp_ifa;
/*
* Do the malloc first in case it blocks.
@ -3773,8 +3752,6 @@ sctp_ingetaddr(struct socket *so, struct sockaddr **addr)
return ECONNRESET;
}
SCTP_INP_RLOCK(inp);
struct sctp_ifa *sctp_ifa;
sin->sin_port = inp->sctp_lport;
if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
if (inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) {

View File

@ -252,11 +252,6 @@ __P((struct sctp_inpcb *, int, struct sctphdr *,
struct sockaddr *, struct sctp_tcb *,
struct sctp_nets *));
#if defined(INET6)
void ip_2_ip6_hdr __P((struct ip6_hdr *, struct ip *));
#endif
int sctp_bindx(struct socket *, int, struct sockaddr_storage *,
int, int, struct proc *);

View File

@ -517,20 +517,13 @@ sctp6_abort(struct socket *so)
#endif
sctp_inpcb_free(inp, 1, 0);
SOCK_LOCK(so);
so->so_snd.sb_cc = 0;
so->so_snd.sb_mb = NULL;
so->so_snd.sb_mbcnt = 0;
SCTP_SB_CLEAR(so->so_snd);
/*
* same for the rcv ones, they are only here for the
* accounting/select.
*/
so->so_rcv.sb_cc = 0;
so->so_rcv.sb_mb = NULL;
so->so_rcv.sb_mbcnt = 0;
/*
* Now null out the reference, we are completely detached.
*/
SCTP_SB_CLEAR(so->so_rcv);
/* Now null out the reference, we are completely detached. */
so->so_pcb = NULL;
SOCK_UNLOCK(so);
} else {
@ -554,7 +547,7 @@ sctp6_attach(struct socket *so, int proto, struct thread *p)
return EINVAL;
if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
error = soreserve(so, sctp_sendspace, sctp_recvspace);
error = SCTP_SORESERVE(so, sctp_sendspace, sctp_recvspace);
if (error)
return error;
}
@ -677,20 +670,13 @@ sctp6_close(struct socket *so)
* the SCTP association.
*/
SOCK_LOCK(so);
so->so_snd.sb_cc = 0;
so->so_snd.sb_mb = NULL;
so->so_snd.sb_mbcnt = 0;
SCTP_SB_CLEAR(so->so_snd);
/*
* same for the rcv ones, they are only here for the
* accounting/select.
*/
so->so_rcv.sb_cc = 0;
so->so_rcv.sb_mb = NULL;
so->so_rcv.sb_mbcnt = 0;
/*
* Now null out the reference, we are completely detached.
*/
SCTP_SB_CLEAR(so->so_rcv);
/* Now null out the reference, we are completely detached. */
so->so_pcb = NULL;
SOCK_UNLOCK(so);
} else {

View File

@ -41,11 +41,11 @@ int sctp6_ctloutput __P((struct socket *, struct sockopt *));
int sctp6_input __P((struct mbuf **, int *, int));
int sctp6_output
__P((struct sctp_inpcb *, struct mbuf *, struct sockaddr *,
struct mbuf *, struct proc *));
void sctp6_ctlinput __P((int, struct sockaddr *, void *));
#endif /* _KERNEL */
#endif