56#if defined(INET) || defined(INET6)
60#include <machine/in_cksum.h>
62#define SCTP_MAX_GAPS_INARRAY 4
1902 struct sockaddr_in6 *sin6;
1909 sctp_gather_internal_ifa_flags(ifa);
1916 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
1921 (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))) {
1925 (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) {
1942#if defined(INET) || defined(INET6)
1962#if defined(INET) || defined(INET6)
1963 if (M_TRAILINGSPACE(m) >= plen) {
2002 struct sockaddr_in6 *sin6;
2008 memcpy(ipv6p->
addr, &sin6->sin6_addr,
2009 sizeof(ipv6p->
addr));
2011 in6_clearscope((
struct in6_addr *)ipv6p->
addr);
2029 struct mbuf *m_at,
int cnt_inits_to,
2033 int cnt, limit_out = 0, total_count;
2053 LIST_FOREACH(sctp_ifnp, &
vrf->
ifnlist, next_ifn) {
2062 LIST_FOREACH(sctp_ifap, &sctp_ifnp->
ifalist, next_ifa) {
2064 if ((sctp_ifap->
address.
sa.sa_family == AF_INET) &&
2071 if ((sctp_ifap->
address.
sa.sa_family == AF_INET6) &&
2095 LIST_FOREACH(sctp_ifnp, &
vrf->
ifnlist, next_ifn) {
2105 LIST_FOREACH(sctp_ifap, &sctp_ifnp->
ifalist, next_ifa) {
2107 if ((sctp_ifap->
address.
sa.sa_family == AF_INET) &&
2114 if ((sctp_ifap->
address.
sa.sa_family == AF_INET6) &&
2127 if ((chunk_len != NULL) &&
2128 (padding_len != NULL) &&
2129 (*padding_len > 0)) {
2130 memset(mtod(m_at, caddr_t)+*chunk_len, 0, *padding_len);
2132 *chunk_len += *padding_len;
2160 if (laddr->
ifa == NULL) {
2190 if (laddr->
ifa == NULL) {
2200 if ((chunk_len != NULL) &&
2201 (padding_len != NULL) &&
2202 (*padding_len > 0)) {
2203 memset(mtod(m_at, caddr_t)+*chunk_len, 0, *padding_len);
2205 *chunk_len += *padding_len;
2258 if (
ifa->address.sa.sa_family != fam) {
2262 if ((dest_is_priv == 0) && (dest_is_loop == 0)) {
2269 if (fam == AF_INET6) {
2275 if (
ifa->src_is_priv && !
ifa->src_is_loop) {
2281 if (
ifa->src_is_glob) {
2295 ifa->src_is_loop,
ifa->src_is_priv,
ifa->src_is_glob);
2297 dest_is_loop, dest_is_priv, dest_is_global);
2299 if ((
ifa->src_is_loop) && (dest_is_priv)) {
2303 if ((
ifa->src_is_glob) && (dest_is_priv)) {
2307 if ((
ifa->src_is_loop) && (dest_is_global)) {
2311 if ((
ifa->src_is_priv) && (dest_is_global)) {
2358 if (
ifa->address.sa.sa_family != fam) {
2361 ifa->address.sa.sa_family, fam);
2367 dest_is_loop, dest_is_priv);
2368 if ((dest_is_loop == 0) && (dest_is_priv == 0)) {
2372 if (fam == AF_INET6) {
2377 if (
ifa->src_is_priv) {
2392 if ((
ifa->src_is_loop == 1) && (dest_is_priv)) {
2398 if ((
ifa->src_is_loop == 1) && (dest_is_global)) {
2416 if (laddr->
ifa == NULL) {
2437 if (laddr->
ifa == NULL) {
2453 int non_asoc_addr_ok,
2496 (non_asoc_addr_ok == 0))
2504 atomic_add_int(&sifa->
refcount, 1);
2522 laddr = LIST_NEXT(laddr, sctp_nxt_addr)) {
2523 if (laddr->
ifa == NULL) {
2535 atomic_add_int(&sifa->
refcount, 1);
2538 if (resettotop == 0) {
2553 laddr = LIST_NEXT(laddr, sctp_nxt_addr)) {
2554 if (laddr->
ifa == NULL) {
2566 atomic_add_int(&sifa->
refcount, 1);
2569 if (resettotop == 0) {
2571 goto once_again_too;
2588 int non_asoc_addr_ok,
2595 uint8_t start_at_beginning = 0;
2639 if (((non_asoc_addr_ok == 0) &&
2641 (non_asoc_addr_ok &&
2647 atomic_add_int(&sifa->
refcount, 1);
2673 if (((non_asoc_addr_ok == 0) &&
2675 (non_asoc_addr_ok &&
2681 atomic_add_int(&sifa->
refcount, 1);
2693 start_at_beginning = 1;
2698 laddr = LIST_NEXT(laddr, sctp_nxt_addr)) {
2699 if (laddr->
ifa == NULL) {
2710 if (((non_asoc_addr_ok == 0) &&
2712 (non_asoc_addr_ok &&
2719 atomic_add_int(&sifa->
refcount, 1);
2722 if (start_at_beginning == 0) {
2724 goto sctp_from_the_top;
2728 start_at_beginning = 0;
2731 start_at_beginning = 1;
2736 laddr = LIST_NEXT(laddr, sctp_nxt_addr)) {
2737 if (laddr->
ifa == NULL) {
2749 if (((non_asoc_addr_ok == 0) &&
2751 (non_asoc_addr_ok &&
2758 atomic_add_int(&sifa->
refcount, 1);
2761 if (start_at_beginning == 0) {
2763 goto sctp_from_the_top2;
2772 int non_asoc_addr_ok,
2780 int num_eligible_addr = 0;
2782 struct sockaddr_in6 sin6, lsa6;
2784 if (fam == AF_INET6) {
2785 memcpy(&sin6, &ro->ro_dst,
sizeof(
struct sockaddr_in6));
2786 (void)sa6_recoverscope(&sin6);
2789 LIST_FOREACH(ifa, &ifn->
ifalist, next_ifa) {
2791 if ((ifa->
address.
sa.sa_family == AF_INET) &&
2798 if ((ifa->
address.
sa.sa_family == AF_INET6) &&
2805 (non_asoc_addr_ok == 0))
2812 if (fam == AF_INET6 &&
2822 if (fam == AF_INET6 &&
2823 IN6_IS_ADDR_LINKLOCAL(&sifa->
address.
sin6.sin6_addr) &&
2824 IN6_IS_ADDR_LINKLOCAL(&sin6.sin6_addr)) {
2829 memcpy(&lsa6, &sifa->
address.
sin6,
sizeof(
struct sockaddr_in6));
2830 (void)sa6_recoverscope(&lsa6);
2831 if (sin6.sin6_scope_id != lsa6.sin6_scope_id) {
2845 if (stcb && fam == AF_INET6 &&
2855 if (stcb && fam == AF_INET &&
2866 if (((non_asoc_addr_ok == 0) &&
2868 (non_asoc_addr_ok &&
2878 if (num_eligible_addr >= addr_wanted) {
2881 num_eligible_addr++;
2890 int non_asoc_addr_ok,
2896 int num_eligible_addr = 0;
2900 if ((
ifa->address.sa.sa_family == AF_INET) &&
2902 &
ifa->address.sin.sin_addr) != 0)) {
2907 if ((
ifa->address.sa.sa_family == AF_INET6) &&
2910 &
ifa->address.sin6.sin6_addr) != 0)) {
2915 (non_asoc_addr_ok == 0)) {
2927 if (((non_asoc_addr_ok == 0) &&
2929 (non_asoc_addr_ok &&
2939 num_eligible_addr++;
2941 return (num_eligible_addr);
2952 int non_asoc_addr_ok,
2955 int cur_addr_num = 0, num_preferred = 0;
2990 goto bound_all_plan_b;
3005 if (num_preferred == 0) {
3010 goto bound_all_plan_b;
3017 if (cur_addr_num >= num_preferred) {
3027 dest_is_priv, cur_addr_num, fam, ro);
3052 if ((
sctp_ifn == looked_at) && looked_at) {
3058 dest_is_loop, dest_is_priv, fam);
3060 "Found ifn:%p %d preferred source addresses\n",
3061 ifn, num_preferred);
3062 if (num_preferred == 0) {
3068 "num preferred:%d on interface:%p cur_addr_num:%d\n",
3069 num_preferred, (
void *)
sctp_ifn, cur_addr_num);
3076 if (cur_addr_num >= num_preferred) {
3080 dest_is_priv, cur_addr_num, fam, ro);
3092 atomic_add_int(&sifa->
refcount, 1);
3096again_with_private_addresses_allowed:
3101 if (emit_ifn == NULL) {
3105 LIST_FOREACH(
sctp_ifa, &emit_ifn->ifalist, next_ifa) {
3124 (non_asoc_addr_ok == 0)) {
3140 if (((non_asoc_addr_ok == 0) &&
3142 (non_asoc_addr_ok &&
3154 atomic_add_int(&sifa->
refcount, 1);
3186 (non_asoc_addr_ok == 0))
3198 if (((non_asoc_addr_ok == 0) &&
3200 (non_asoc_addr_ok &&
3219 goto again_with_private_addresses_allowed;
3220 }
else if (retried == 1) {
3252 (non_asoc_addr_ok == 0))
3257 if (tmp_sifa == NULL) {
3260 if (tmp_sifa == sifa) {
3268 if (((non_asoc_addr_ok == 0) &&
3270 (non_asoc_addr_ok &&
3289 atomic_add_int(&sifa->
refcount, 1);
3304 uint8_t dest_is_priv, dest_is_loop;
3310 struct sockaddr_in6 *to6 = (
struct sockaddr_in6 *)&ro->ro_dst;
3376 if (ro->ro_nh == NULL) {
3382 if (ro->ro_nh == NULL) {
3385 fam = ro->ro_dst.sa_family;
3386 dest_is_priv = dest_is_loop = 0;
3406 if (IN6_IS_ADDR_LOOPBACK(&to6->sin6_addr) ||
3419 }
else if (IN6_IS_ADDR_LINKLOCAL(&to6->sin6_addr)) {
3433 dest_is_priv, dest_is_loop,
3434 non_asoc_addr_ok, fam);
3443 vrf_id, dest_is_priv,
3445 non_asoc_addr_ok, fam);
3463 int tot_len, rem_len, cmsg_data_len, cmsg_data_off, off;
3472 for (off = 0; off < tot_len; off += CMSG_ALIGN(cmh.cmsg_len)) {
3473 rem_len = tot_len - off;
3474 if (rem_len < (
int)CMSG_ALIGN(
sizeof(cmh))) {
3478 m_copydata(control, off,
sizeof(cmh), (caddr_t)&cmh);
3479 if (cmh.cmsg_len < CMSG_ALIGN(
sizeof(cmh))) {
3483 if ((cmh.cmsg_len > INT_MAX) || ((
int)cmh.cmsg_len > rem_len)) {
3487 cmsg_data_len = (int)cmh.cmsg_len - CMSG_ALIGN(
sizeof(cmh));
3488 cmsg_data_off = off + CMSG_ALIGN(
sizeof(cmh));
3490 ((c_type == cmh.cmsg_type) ||
3495 if (c_type == cmh.cmsg_type) {
3496 if (cpsize > INT_MAX) {
3499 if (cmsg_data_len < (
int)cpsize) {
3503 m_copydata(control, cmsg_data_off, (
int)cpsize, (caddr_t)data);
3515 switch (cmh.cmsg_type) {
3517 if (cmsg_data_len < (
int)
sizeof(
struct sctp_sndinfo)) {
3520 m_copydata(control, cmsg_data_off,
sizeof(
struct sctp_sndinfo), (caddr_t)&sndinfo);
3528 if (cmsg_data_len < (
int)
sizeof(
struct sctp_prinfo)) {
3531 m_copydata(control, cmsg_data_off,
sizeof(
struct sctp_prinfo), (caddr_t)&prinfo);
3543 m_copydata(control, cmsg_data_off,
sizeof(
struct sctp_authinfo), (caddr_t)&authinfo);
3566 struct sockaddr_in6 sin6;
3568 int tot_len, rem_len, cmsg_data_len, cmsg_data_off, off;
3571 for (off = 0; off < tot_len; off += CMSG_ALIGN(cmh.cmsg_len)) {
3572 rem_len = tot_len - off;
3573 if (rem_len < (
int)CMSG_ALIGN(
sizeof(cmh))) {
3578 m_copydata(control, off,
sizeof(cmh), (caddr_t)&cmh);
3579 if (cmh.cmsg_len < CMSG_ALIGN(
sizeof(cmh))) {
3584 if ((cmh.cmsg_len > INT_MAX) || ((
int)cmh.cmsg_len > rem_len)) {
3589 cmsg_data_len = (int)cmh.cmsg_len - CMSG_ALIGN(
sizeof(cmh));
3590 cmsg_data_off = off + CMSG_ALIGN(
sizeof(cmh));
3592 switch (cmh.cmsg_type) {
3594 if (cmsg_data_len < (
int)
sizeof(
struct sctp_initmsg)) {
3598 m_copydata(control, cmsg_data_off,
sizeof(
struct sctp_initmsg), (caddr_t)&initmsg);
3599 if (initmsg.sinit_max_attempts)
3601 if (initmsg.sinit_num_ostreams)
3603 if (initmsg.sinit_max_instreams)
3605 if (initmsg.sinit_max_init_timeo)
3610#if defined(SCTP_DETAILED_STR_STATS)
3623 if (tmp_str != NULL) {
3634#if defined(SCTP_DETAILED_STR_STATS)
3653 if (cmsg_data_len < (
int)
sizeof(
struct in_addr)) {
3661 m_copydata(control, cmsg_data_off,
sizeof(
struct in_addr), (caddr_t)&sin.
sin_addr);
3677 if (cmsg_data_len < (
int)
sizeof(
struct in6_addr)) {
3681 memset(&sin6, 0,
sizeof(
struct sockaddr_in6));
3682 sin6.sin6_family = AF_INET6;
3683 sin6.sin6_len =
sizeof(
struct sockaddr_in6);
3684 sin6.sin6_port = stcb->
rport;
3685 m_copydata(control, cmsg_data_off,
sizeof(
struct in6_addr), (caddr_t)&sin6.sin6_addr);
3686 if (IN6_IS_ADDR_UNSPECIFIED(&sin6.sin6_addr) ||
3687 IN6_IS_ADDR_MULTICAST(&sin6.sin6_addr)) {
3692 if (IN6_IS_ADDR_V4MAPPED(&sin6.sin6_addr)) {
3693 in6_sin6_2_sin(&sin, &sin6);
3696 IN_MULTICAST(ntohl(sin.sin_addr.s_addr))) {
3722#if defined(INET) || defined(INET6)
3724sctp_findassociation_cmsgs(
struct sctp_inpcb **inp_p,
3726 struct mbuf *control,
3732 struct sockaddr *addr;
3737 struct sockaddr_in6 sin6;
3739 int tot_len, rem_len, cmsg_data_len, cmsg_data_off, off;
3742 for (off = 0; off < tot_len; off += CMSG_ALIGN(cmh.cmsg_len)) {
3743 rem_len = tot_len - off;
3744 if (rem_len < (
int)CMSG_ALIGN(
sizeof(cmh))) {
3749 m_copydata(control, off,
sizeof(cmh), (caddr_t)&cmh);
3750 if (cmh.cmsg_len < CMSG_ALIGN(
sizeof(cmh))) {
3755 if ((cmh.cmsg_len > INT_MAX) || ((
int)cmh.cmsg_len > rem_len)) {
3760 cmsg_data_len = (int)cmh.cmsg_len - CMSG_ALIGN(
sizeof(cmh));
3761 cmsg_data_off = off + CMSG_ALIGN(
sizeof(cmh));
3763 switch (cmh.cmsg_type) {
3766 if (cmsg_data_len < (
int)
sizeof(
struct in_addr)) {
3771 sin.sin_family = AF_INET;
3773 sin.sin_port = port;
3774 m_copydata(control, cmsg_data_off,
sizeof(
struct in_addr), (caddr_t)&sin.sin_addr);
3775 addr = (
struct sockaddr *)&sin;
3780 if (cmsg_data_len < (
int)
sizeof(
struct in6_addr)) {
3784 memset(&sin6, 0,
sizeof(
struct sockaddr_in6));
3785 sin6.sin6_family = AF_INET6;
3786 sin6.sin6_len =
sizeof(
struct sockaddr_in6);
3787 sin6.sin6_port = port;
3788 m_copydata(control, cmsg_data_off,
sizeof(
struct in6_addr), (caddr_t)&sin6.sin6_addr);
3790 if (IN6_IS_ADDR_V4MAPPED(&sin6.sin6_addr)) {
3791 in6_sin6_2_sin(&sin, &sin6);
3792 addr = (
struct sockaddr *)&sin;
3795 addr = (
struct sockaddr *)&sin6;
3818 struct mbuf *copy_init, *copy_initack, *m_at, *sig, *mret;
3825 M_NOWAIT, 1, MT_DATA);
3829 copy_init =
SCTP_M_COPYM(init, init_offset, M_COPYALL, M_NOWAIT);
3830 if (copy_init == NULL) {
3834#ifdef SCTP_MBUF_LOGGING
3839 copy_initack =
SCTP_M_COPYM(initack, initack_offset, M_COPYALL,
3841 if (copy_initack == NULL) {
3846#ifdef SCTP_MBUF_LOGGING
3878 for (m_at = copy_initack; m_at; m_at =
SCTP_BUF_NEXT(m_at)) {
3894 *signature = (
uint8_t *)mtod(sig, caddr_t);
3909#if defined(INET) || defined(INET6)
3911sctp_handle_no_route(
struct sctp_tcb *stcb,
3959 struct sockaddr *to,
3964 int nofragment_flag,
3993#if defined(INET) || defined(INET6)
3996#if defined(INET) || defined(INET6)
3999 struct udphdr *udp = NULL;
4008#if defined(INET) || defined(INET6)
4016 if ((auth != NULL) && (stcb != NULL)) {
4021 tos_value = net->
dscp;
4028 switch (to->sa_family) {
4032 struct ip *
ip = NULL;
4038 len +=
sizeof(
struct udphdr);
4051 m->m_pkthdr.flowid = net->
flowid;
4054 m->m_pkthdr.flowid = mflowid;
4055 M_HASHTYPE_SET(m, mflowtype);
4058 ip = mtod(m,
struct ip *);
4061 if (tos_value == 0) {
4073 if ((nofragment_flag) && (port == 0)) {
4092 memset(&iproute, 0,
sizeof(iproute));
4093 memcpy(&ro->ro_dst, to, to->sa_len);
4101 if (net && out_of_asoc_ok == 0) {
4118 sctp_handle_no_route(stcb, net, so_locked);
4121 return (EHOSTUNREACH);
4125 if (over_addr == NULL) {
4132 if (_lsrc == NULL) {
4133 sctp_handle_no_route(stcb, net, so_locked);
4136 return (EHOSTUNREACH);
4147 sctp_handle_no_route(stcb, net, so_locked);
4150 return (EHOSTUNREACH);
4152 udp = (
struct udphdr *)((caddr_t)
ip +
sizeof(
struct ip));
4178 if (ro->ro_nh == NULL) {
4184 sctp_handle_no_route(stcb, net, so_locked);
4187 return (EHOSTUNREACH);
4189 if (ro != &iproute) {
4190 memcpy(&iproute, ro,
sizeof(*ro));
4213 m->m_pkthdr.csum_flags = CSUM_SCTP;
4214 m->m_pkthdr.csum_data = offsetof(
struct sctphdr, checksum);
4217#ifdef SCTP_PACKET_LOGGING
4219 sctp_packet_log(o_pak);
4237 if ((ro->ro_nh != NULL) && (net->
ro.
_s_addr) &&
4244 mtu -=
sizeof(
struct udphdr);
4246 if (mtu < net->mtu) {
4253 }
else if (ro->ro_nh == NULL) {
4271 struct route_in6 ip6route;
4273 struct sockaddr_in6 *sin6, tmp, *lsa6, lsa6_tmp;
4275 struct sockaddr_in6 lsa6_storage;
4277 u_short prev_port = 0;
4281 flowlabel = net->flowlabel;
4283 flowlabel = stcb->
asoc.default_flowlabel;
4285 flowlabel = inp->
sctp_ep.default_flowlabel;
4287 if (flowlabel == 0) {
4293 flowlabel = ntohl(((
struct inpcb *)inp)->inp_flow);
4295 flowlabel &= 0x000fffff;
4298 len +=
sizeof(
struct udphdr);
4311 m->m_pkthdr.flowid = net->
flowid;
4314 m->m_pkthdr.flowid = mflowid;
4315 M_HASHTYPE_SET(m, mflowtype);
4319 ip6h = mtod(m,
struct ip6_hdr *);
4321 sin6 = (
struct sockaddr_in6 *)to;
4326 if (sa6_embedscope(sin6,
MODULE_GLOBAL(ip6_use_defzone)) != 0) {
4332 memset(&ip6route, 0,
sizeof(ip6route));
4334 memcpy(&ro->ro_dst, sin6, sin6->sin6_len);
4342 if (tos_value == 0) {
4348 tos_value = (ntohl(((
struct inpcb *)inp)->inp_flow) >> 20) & 0xff;
4356 flowinfo |= tos_value;
4358 flowinfo |= flowlabel;
4359 ip6h->ip6_flow = htonl(flowinfo);
4365 ip6h->ip6_plen = htons((
uint16_t)(packet_length -
sizeof(
struct ip6_hdr)));
4366 ip6h->
ip6_dst = sin6->sin6_addr;
4374 memset(&lsa6_tmp, 0,
sizeof(lsa6_tmp));
4375 lsa6_tmp.sin6_family = AF_INET6;
4376 lsa6_tmp.sin6_len =
sizeof(lsa6_tmp);
4378 if (net && out_of_asoc_ok == 0) {
4386 sin6 = (
struct sockaddr_in6 *)&net->
ro.
_l_addr;
4388 if (sa6_embedscope(sin6,
MODULE_GLOBAL(ip6_use_defzone)) != 0) {
4400 (void)sa6_recoverscope(sin6);
4406 sctp_handle_no_route(stcb, net, so_locked);
4409 return (EHOSTUNREACH);
4413 sin6 = (
struct sockaddr_in6 *)&ro->ro_dst;
4415 if (sa6_embedscope(sin6,
MODULE_GLOBAL(ip6_use_defzone)) != 0) {
4420 if (over_addr == NULL) {
4427 if (_lsrc == NULL) {
4428 sctp_handle_no_route(stcb, net, so_locked);
4431 return (EHOSTUNREACH);
4436 lsa6->sin6_addr = over_addr->
sin6.sin6_addr;
4439 (void)sa6_recoverscope(sin6);
4441 lsa6->sin6_port = inp->sctp_lport;
4443 if (ro->ro_nh == NULL) {
4449 sctp_handle_no_route(stcb, net, so_locked);
4452 return (EHOSTUNREACH);
4458 memset(&lsa6_storage, 0,
sizeof(lsa6_storage));
4459 lsa6_storage.sin6_family = AF_INET6;
4460 lsa6_storage.sin6_len =
sizeof(lsa6_storage);
4461 lsa6_storage.sin6_addr = lsa6->sin6_addr;
4462 if ((error = sa6_recoverscope(&lsa6_storage)) != 0) {
4468 lsa6_storage.sin6_addr = lsa6->sin6_addr;
4469 lsa6_storage.sin6_port = inp->sctp_lport;
4470 lsa6 = &lsa6_storage;
4471 ip6h->
ip6_src = lsa6->sin6_addr;
4475 sctp_handle_no_route(stcb, net, so_locked);
4478 return (EHOSTUNREACH);
4480 udp = (
struct udphdr *)((caddr_t)ip6h +
sizeof(
struct ip6_hdr));
4504 sin6->sin6_addr = ip6h->
ip6_dst;
4505 lsa6->sin6_addr = ip6h->
ip6_src;
4514 sin6 = (
struct sockaddr_in6 *)&net->
ro.
_l_addr;
4519 prev_scope = sin6->sin6_scope_id;
4520 prev_port = sin6->sin6_port;
4537 m->m_pkthdr.csum_flags = CSUM_SCTP_IPV6;
4538 m->m_pkthdr.csum_data = offsetof(
struct sctphdr, checksum);
4542#ifdef SCTP_PACKET_LOGGING
4544 sctp_packet_log(o_pak);
4547 SCTP_IP6_OUTPUT(ret, o_pak, (
struct route_in6 *)ro, &ifp, inp, vrf_id);
4550 sin6->sin6_scope_id = prev_scope;
4551 sin6->sin6_port = prev_port;
4570 if (ro->ro_nh == NULL) {
4579 if ((ro->ro_nh != NULL) && (net->
ro.
_s_addr) &&
4586 mtu -=
sizeof(
struct udphdr);
4588 if (mtu < net->mtu) {
4595 }
else if (ifp != NULL) {
4596 if ((ND_IFINFO(ifp)->linkmtu > 0) &&
4607 ((
struct sockaddr *)to)->sa_family);
4617 struct mbuf *m, *m_last;
4624 int cnt_inits_to = 0;
4626 uint16_t num_ext, chunk_len, padding_len, parameter_len;
4631 net = TAILQ_FIRST(&stcb->
asoc.
nets);
4693 chunk_len += parameter_len;
4702 chunk_len += parameter_len;
4711 chunk_len += parameter_len;
4720 chunk_len += parameter_len;
4755 padding_len =
SCTP_SIZE32(parameter_len) - parameter_len;
4756 chunk_len += parameter_len;
4764 if (padding_len > 0) {
4765 memset(mtod(m, caddr_t)+chunk_len, 0, padding_len);
4766 chunk_len += padding_len;
4773 padding_len =
SCTP_SIZE32(parameter_len) - parameter_len;
4774 chunk_len += parameter_len;
4780 if (padding_len > 0) {
4781 memset(mtod(m, caddr_t)+chunk_len, 0, padding_len);
4782 chunk_len += padding_len;
4791 padding_len =
SCTP_SIZE32(parameter_len) - parameter_len;
4792 chunk_len += parameter_len;
4798 if (padding_len > 0) {
4799 memset(mtod(m, caddr_t)+chunk_len, 0, padding_len);
4800 chunk_len += padding_len;
4809 padding_len =
SCTP_SIZE32(parameter_len) - parameter_len;
4810 chunk_len += parameter_len;
4818 if (padding_len > 0) {
4819 memset(mtod(m, caddr_t)+chunk_len, 0, padding_len);
4820 chunk_len += padding_len;
4829 chunk_len += parameter_len;
4835 if (padding_len > 0) {
4836 memset(mtod(m, caddr_t)+chunk_len, 0, padding_len);
4837 chunk_len += padding_len;
4857 padding_len = 4 - 2 * i;
4858 chunk_len += parameter_len;
4871 &padding_len, &chunk_len);
4874 if (padding_len > 0) {
4883 m, 0, NULL, 0, 0, 0, 0,
4884 inp->sctp_lport, stcb->
rport, htonl(0),
4889 if (error == ENOBUFS) {
4902 int param_offset,
int *abort_processing,
4923 struct mbuf *mat, *m_tmp, *op_err, *op_err_last;
4924 int at, limit, pad_needed;
4927 *abort_processing = 0;
4928 if (cookie_found != NULL) {
4939 while ((phdr != NULL) && ((
size_t)limit >=
sizeof(
struct sctp_paramhdr))) {
4942 if ((plen > limit) || (plen <
sizeof(
struct sctp_paramhdr))) {
4965 if (cookie_found != NULL) {
5063 *abort_processing = 1;
5075 if (op_err != NULL) {
5106 if ((ptype & 0x4000) == 0x4000) {
5109 if (op_err == NULL) {
5130 op_err_last = op_err;
5133 if (op_err != NULL) {
5137 if (pad_needed > 0) {
5140 if (op_err_last == NULL) {
5144 goto more_processing;
5146 if (M_TRAILINGSPACE(op_err_last) < (
int)
sizeof(
struct sctp_paramhdr)) {
5148 if (m_tmp == NULL) {
5152 goto more_processing;
5157 op_err_last = m_tmp;
5168 goto more_processing;
5174 if (plen % 4 != 0) {
5175 pad_needed = 4 - (plen % 4);
5182 if ((ptype & 0x8000) == 0x0000) {
5197 *abort_processing = 1;
5243 struct mbuf *in_initpkt,
int offset,
int limit,
struct sockaddr *src,
5244 struct mbuf **op_err)
5246 struct sockaddr *sa_touse;
5247 struct sockaddr *sa;
5254 struct sockaddr_in6 sin6, *sa6;
5257 bool fnd, check_src;
5261 memset(&sin4, 0,
sizeof(sin4));
5266 memset(&sin6, 0,
sizeof(sin6));
5267 sin6.sin6_family = AF_INET6;
5268 sin6.sin6_len =
sizeof(sin6);
5272 switch (src->sa_family) {
5293 TAILQ_FOREACH(net, &asoc->
nets, sctp_next) {
5294 sa = (
struct sockaddr *)&net->
ro.
_l_addr;
5295 if (sa->sa_family == src->sa_family) {
5297 if (sa->sa_family == AF_INET) {
5309 if (sa->sa_family == AF_INET6) {
5310 struct sockaddr_in6 *src6;
5312 sa6 = (
struct sockaddr_in6 *)sa;
5313 src6 = (
struct sockaddr_in6 *)src;
5314 if (SCTP6_ARE_ADDR_EQUAL(sa6, src6)) {
5340 if (offset + plen > limit) {
5367 sa_touse = (
struct sockaddr *)&sin4;
5389 memcpy((caddr_t)&sin6.sin6_addr, p6->
addr,
5391 sa_touse = (
struct sockaddr *)&sin6;
5403 TAILQ_FOREACH(net, &asoc->
nets, sctp_next) {
5404 sa = (
struct sockaddr *)&net->
ro.
_l_addr;
5405 if (sa->sa_family != sa_touse->sa_family) {
5409 if (sa->sa_family == AF_INET) {
5419 if (sa->sa_family == AF_INET6) {
5420 sa6 = (
struct sockaddr_in6 *)sa;
5421 if (SCTP6_ARE_ADDR_EQUAL(
5442 if (offset >= limit) {
5458 struct sctp_nets *src_net,
struct mbuf *init_pkt,
5459 int iphlen,
int offset,
5460 struct sockaddr *src,
struct sockaddr *dst,
5466 struct mbuf *m, *m_tmp, *m_last, *m_cookie, *op_err;
5480 struct sockaddr_in6 *dst6 = (
struct sockaddr_in6 *)dst;
5481 struct sockaddr_in6 *src6 = (
struct sockaddr_in6 *)src;
5482 struct sockaddr_in6 *sin6;
5484 struct sockaddr *to;
5488 int cnt_inits_to = 0;
5491 int nat_friendly = 0;
5494 uint16_t num_ext, chunk_len, padding_len, parameter_len;
5501 if ((asoc != NULL) &&
5509 mflowtype, mflowid, inp->
fibnum,
5513 if (src_net != NULL && (src_net->
port != port)) {
5523 "Remote encapsulation port changed");
5525 mflowtype, mflowid, inp->
fibnum,
5535 &nat_friendly, NULL);
5538 if (op_err == NULL) {
5541 SCTP_SNPRINTF(msg,
sizeof(msg),
"%s:%d at %s", __FILE__, __LINE__, __func__);
5547 mflowtype, mflowid, inp->
fibnum,
5610 switch (dst->sa_family) {
5646 memcpy(&stc.
address, &src6->sin6_addr,
sizeof(
struct in6_addr));
5647 stc.
scope_id = ntohs(in6_getscope(&src6->sin6_addr));
5653 }
else if (IN6_IS_ADDR_LINKLOCAL(&src6->sin6_addr) ||
5654 IN6_IS_ADDR_LINKLOCAL(&dst6->sin6_addr)) {
5680 }
else if (IN6_IS_ADDR_SITELOCAL(&src6->sin6_addr) ||
5681 IN6_IS_ADDR_SITELOCAL(&dst6->sin6_addr)) {
5689 memcpy(&stc.
laddress, &dst6->sin6_addr,
sizeof(
struct in6_addr));
5712 TAILQ_FOREACH(lnet, &asoc->
nets, sctp_next) {
5714 if (IN6_IS_ADDR_LINKLOCAL(&lnet->
ro.
_l_addr.
sin6.sin6_addr)) {
5725 to = (
struct sockaddr *)&net->
ro.
_l_addr;
5726 switch (to->sa_family) {
5762 sin6 = (
struct sockaddr_in6 *)to;
5763 memcpy(&stc.
address, &sin6->sin6_addr,
5764 sizeof(
struct in6_addr));
5766 stc.
scope_id = sin6->sin6_scope_id;
5784 sizeof(
struct in6_addr));
5800 initack->ch.chunk_flags = 0;
5802 initack->ch.chunk_length = 0;
5804 if ((asoc != NULL) &&
5809 initack->init.initiate_tag = htonl(asoc->
my_vtag);
5815 atomic_add_int(&asoc->
refcnt, 1);
5828 initack->init.initiate_tag = htonl(vtag);
5831 initack->init.initial_tsn = htonl(itsn);
5833 atomic_subtract_int(&asoc->
refcnt, 1);
5840 initack->init.initiate_tag = htonl(vtag);
5848 stc.
my_vtag = initack->init.initiate_tag;
5872 if (his_limit < i_want) {
5877 initack->init.num_outbound_streams = htons(i_want);
5880 initack->init.num_inbound_streams =
5890 chunk_len += parameter_len;
5900 chunk_len += parameter_len;
5910 chunk_len += parameter_len;
5919 chunk_len += parameter_len;
5962 padding_len =
SCTP_SIZE32(parameter_len) - parameter_len;
5963 chunk_len += parameter_len;
5973 if (padding_len > 0) {
5974 memset(mtod(m, caddr_t)+chunk_len, 0, padding_len);
5975 chunk_len += padding_len;
5985 padding_len =
SCTP_SIZE32(parameter_len) - parameter_len;
5986 chunk_len += parameter_len;
5988 if (padding_len > 0) {
5989 memset(mtod(m, caddr_t)+chunk_len, 0, padding_len);
5990 chunk_len += padding_len;
6000 padding_len =
SCTP_SIZE32(parameter_len) - parameter_len;
6001 chunk_len += parameter_len;
6003 if (padding_len > 0) {
6004 memset(mtod(m, caddr_t)+chunk_len, 0, padding_len);
6005 chunk_len += padding_len;
6015 padding_len =
SCTP_SIZE32(parameter_len) - parameter_len;
6016 chunk_len += parameter_len;
6035 &padding_len, &chunk_len);
6037 if (padding_len > 0) {
6038 memset(mtod(m, caddr_t)+chunk_len, 0, padding_len);
6039 chunk_len += padding_len;
6047 for (m_tmp = op_err; m_tmp != NULL; m_tmp =
SCTP_BUF_NEXT(m_tmp)) {
6050 padding_len =
SCTP_SIZE32(parameter_len) - parameter_len;
6055 chunk_len += parameter_len;
6057 if (padding_len > 0) {
6059 if (m_last == NULL) {
6064 chunk_len += padding_len;
6069 if (m_cookie == NULL) {
6077 for (m_tmp = m_cookie; m_tmp != NULL; m_tmp =
SCTP_BUF_NEXT(m_tmp)) {
6083 padding_len =
SCTP_SIZE32(parameter_len) - parameter_len;
6084 chunk_len += parameter_len;
6090 initack->ch.chunk_length = htons(chunk_len);
6104 if (padding_len > 0) {
6123 if (error == ENOBUFS) {
6184 freed_spc += ret_spc;
6185 if (freed_spc >= dataout) {
6207 freed_spc += ret_spc;
6208 if (freed_spc >= dataout) {
6243 KASSERT(overhead % 4 == 0,
6244 (
"overhead (%u) not a multiple of 4", overhead));
6250 (
"Association MTU (%u) too small for overhead (%u)",
6253 KASSERT(frag_point % 4 == 0,
6254 (
"frag_point (%u) not a multiple of 4", frag_point));
6260 return (frag_point);
6293 tv.tv_usec = (sp->
timetolive * 1000) % 1000000;
6298 timevaladd(&sp->
ts, &tv);
6311 "Unknown PR_SCTP policy %u.\n",
6399 if (hold_stcb_lock == 0) {
6408 if (hold_stcb_lock == 0) {
6420 struct mbuf *outchain,
6421 struct mbuf **endofchain,
6427 struct mbuf *appendchain;
6431 if (endofchain == NULL) {
6438 if (can_take_mbuf) {
6439 appendchain = clonechain;
6442 (sizeofcpy <= (
int)((((
SCTP_BASE_SYSCTL(sctp_mbuf_threshold_count) - 1) * MLEN) + MHLEN)))) {
6444 if (*endofchain == NULL) {
6446 if (outchain == NULL) {
6450 if (outchain == NULL) {
6454 *endofchain = outchain;
6472 if (*endofchain == NULL) {
6482 len = (int)M_TRAILINGSPACE(*endofchain);
6485 len = (int)M_TRAILINGSPACE(*endofchain);
6488 cp = (mtod((*endofchain), caddr_t)+
SCTP_BUF_LEN((*endofchain)));
6491 if (len >= sizeofcpy) {
6493 m_copydata(clonechain, 0, sizeofcpy, cp);
6498 m_copydata(clonechain, 0, len, cp);
6510 cp = mtod((*endofchain), caddr_t);
6511 m_copydata(clonechain, len, sizeofcpy, cp);
6517 appendchain =
SCTP_M_COPYM(clonechain, 0, M_COPYALL, M_NOWAIT);
6518#ifdef SCTP_MBUF_LOGGING
6525 if (appendchain == NULL) {
6533 if (*endofchain != NULL) {
6567 return (appendchain);
6577 int control_only,
int from_where,
6578 struct timeval *now,
int *now_filled,
6579 uint32_t frag_point,
int so_locked);
6588 int added_control = 0;
6589 int un_sent, do_chunk_output = 1;
6594 if (ca->
m == NULL) {
6608#ifdef SCTP_MBUF_LOGGING
6628 0, M_NOWAIT, 1, MT_DATA);
6657 goto no_chunk_output;
6694 do_chunk_output = 0;
6717 struct mbuf *op_err;
6722 "%s:%d at %s", __FILE__, __LINE__, __func__);
6729 goto no_chunk_output;
6743 do_chunk_output = 0;
6745 if (do_chunk_output)
6747 else if (added_control) {
6749 int num_out, reason, now_filled = 0;
6752 &reason, 1, 1, &now, &now_filled,
6793 struct mbuf *ret, *at;
6794 ssize_t left, willcpy, cancpy, error;
6804 cancpy = (int)M_TRAILINGSPACE(ret);
6805 willcpy = min(cancpy, left);
6809 error = uiomove(mtod(at, caddr_t), (
int)willcpy, uio);
6825 cancpy = (int)M_TRAILINGSPACE(at);
6826 willcpy = min(cancpy, left);
6875 ca->
sndlen = uio->uio_resid;
6877 if (ca->
m == NULL) {
6902 inp->
sctp_flags &= ~SCTP_PCB_FLAGS_SND_ITERATOR_UP;
6968 for (i = 0; i < bundle_at; i++) {
6978 data_list[i]->
do_rtt = 0;
6984 if (data_list[i]->
whoTo == NULL) {
6985 data_list[i]->
whoTo = net;
6995 tpp = TAILQ_PREV(tp1, sctpchunk_listhead, sctp_next);
6997 TAILQ_INSERT_BEFORE(tp1, data_list[i], sctp_next);
7004 TAILQ_INSERT_AFTER(&
asoc->
sent_queue, tp1, data_list[i], sctp_next);
7019#ifdef SCTP_AUDITING_ENABLED
7020 sctp_audit_log(0xC2, 3);
7083 goto clean_up_anyway;
7103 if (space_left >= length) {
7120 return (space_left);
7131 if ((length <= space_left) ||
7140 if (space_left >= min(
SCTP_BASE_SYSCTL(sctp_min_split_point), frag_point)) {
7142 return (min(space_left, frag_point));
7177 if (send_lock_up == 0) {
7188 SCTP_PRINTF(
"Huh? Stream:%d lm_in_c=%d but queue is NULL\n",
7208 SCTP_PRINTF(
"Gak, put out entire msg with NO end!-1\n");
7209 SCTP_PRINTF(
"sender_done:%d len:%d msg_comp:%d put_last_out:%d send_lock:%d\n",
7216 if (send_lock_up == 0) {
7261 if (send_lock_up == 0) {
7289 to_move = min(length, frag_point);
7290 if (to_move == length) {
7318 if (to_move >= llen) {
7320 if (send_lock_up == 0) {
7368 memset(chk, 0,
sizeof(*chk));
7371 if (to_move >= length) {
7377 if (to_move < sp->length) {
7391 if (chk->
data == NULL) {
7398#ifdef SCTP_MBUF_LOGGING
7404 m_adj(sp->
data, to_move);
7417 panic(
"Huh, freing tail? - TSNH");
7444 if (to_move > length) {
7450 panic(
"Huh, how can to_move be larger?");
7456 atomic_subtract_int(&sp->
length, to_move);
7459 if (M_LEADINGSPACE(chk->
data) < leading) {
7470 if (send_lock_up == 0) {
7474 if (sp->
data == NULL) {
7487 atomic_add_int(&sp->
length, to_move);
7497 M_ALIGN(chk->
data, 4);
7501 if (chk->
data == NULL) {
7504 panic(
"prepend fails HELP?");
7582#ifdef SCTP_ASOCLOG_OF_TSNS
7585 asoc->tsn_out_at = 0;
7586 asoc->tsn_out_wrapped = 1;
7588 asoc->out_tsnlog[asoc->tsn_out_at].tsn = chk->
rec.
data.
tsn;
7589 asoc->out_tsnlog[asoc->tsn_out_at].strm = chk->
rec.
data.
sid;
7590 asoc->out_tsnlog[asoc->tsn_out_at].seq = chk->
rec.
data.
mid;
7591 asoc->out_tsnlog[asoc->tsn_out_at].sz = chk->
send_size;
7593 asoc->out_tsnlog[asoc->tsn_out_at].stcb = (
void *)stcb;
7594 asoc->out_tsnlog[asoc->tsn_out_at].in_pos = asoc->tsn_out_at;
7595 asoc->out_tsnlog[asoc->tsn_out_at].in_out = 2;
7640 SCTP_PRINTF(
"Gak, put out entire msg with NO end!-2\n");
7641 SCTP_PRINTF(
"sender_done:%d len:%d msg_comp:%d put_last_out:%d send_lock:%d\n",
7648 if (send_lock_up == 0) {
7672 TAILQ_INSERT_TAIL(&asoc->
send_queue, chk, sctp_next);
7683 uint32_t frag_point,
int eeor_mode,
int *quit_now,
7688 uint32_t space_left, moved, total_moved;
7707 space_left = net->
mtu;
7714 space_left &= 0xfffffffc;
7718 while ((space_left > 0) && (strq != NULL)) {
7720 frag_point, &giveup, eeor_mode,
7722 if ((giveup != 0) || (bail != 0)) {
7726 total_moved += moved;
7727 if (space_left >= moved) {
7728 space_left -= moved;
7737 space_left &= 0xfffffffc;
7744 if (total_moved == 0) {
7788 TAILQ_FOREACH(chk, &asoc->
send_queue, sctp_next) {
7802 int control_only,
int from_where,
7803 struct timeval *now,
int *now_filled,
7804 uint32_t frag_point,
int so_locked)
7818 struct sctp_nets *net, *start_at, *sack_goes_to = NULL, *old_start_at = NULL;
7819 struct mbuf *outchain, *endoutchain;
7824 int no_fragmentflg, error;
7825 unsigned int max_rwnd_per_dest, max_send_per_dest;
7826 int one_chunk, hbflag, skip_data_for_this_net;
7827 int asconf,
cookie, no_out_cnt;
7828 int bundle_at, ctl_cnt, no_data_chunks, eeor_mode;
7829 unsigned int mtu, r_mtu, omtu, mx_mtu, to_out;
7834 int override_ok = 1;
7835 int skip_fill_up = 0;
7836 int data_auth_reqd = 0;
7854 ctl_cnt = no_out_cnt = asconf =
cookie = 0;
7860#ifdef SCTP_AUDITING_ENABLED
7861 sctp_audit_log(0xC2, 2);
7890 if (no_data_chunks &&
7893 goto nothing_to_send;
7898 sack_goes_to = chk->
whoTo;
7907 max_send_per_dest = 0;
7908 if (no_data_chunks == 0) {
7910 TAILQ_FOREACH(chk, &asoc->
send_queue, sctp_next) {
7911 if (chk->
whoTo == NULL) {
7921 if ((no_data_chunks == 0) &&
7922 (skip_fill_up == 0) &&
7924 TAILQ_FOREACH(net, &asoc->
nets, sctp_next) {
7982 if (start_at == NULL) {
7984 start_at = TAILQ_FIRST(&asoc->
nets);
7987 if (start_at == NULL) {
7988 start_at = TAILQ_FIRST(&asoc->
nets);
7993 start_at = TAILQ_FIRST(&asoc->
nets);
7996 if (chk->
whoTo == NULL) {
8005 old_start_at = NULL;
8007 for (net = start_at; net != NULL; net = TAILQ_NEXT(net, sctp_next)) {
8010 if (old_start_at && (old_start_at == net)) {
8025 endoutchain = outchain = NULL;
8031 skip_data_for_this_net = 1;
8033 skip_data_for_this_net = 0;
8035 switch (((
struct sockaddr *)&net->
ro.
_l_addr)->sa_family) {
8074 if (chk->
whoTo == NULL) {
8085 if (chk->
whoTo != net) {
8089 if (chk->
data == NULL) {
8104 if ((auth == NULL) &&
8111 if ((chk->
send_size < (
int)(mtu - omtu)) ||
8127 if ((auth == NULL) &&
8141 if (outchain == NULL) {
8171 if (chk->
whoTo == NULL) {
8189 if (*now_filled == 0) {
8197 outchain, auth_offset, auth,
8199 no_fragmentflg, 0, asconf,
8200 inp->sctp_lport, stcb->
rport,
8210 if (from_where == 0) {
8213 if (error == ENOBUFS) {
8218 if (error == EHOSTUNREACH) {
8236 outchain = endoutchain = NULL;
8240 *num_out += ctl_cnt;
8272 if ((sack_goes_to) &&
8274 (chk->
whoTo != sack_goes_to)) {
8280 if (chk->
whoTo == net) {
8286 }
else if (sack_goes_to == net) {
8291 goto skip_net_check;
8294 if (chk->
whoTo == NULL) {
8305 if (chk->
whoTo != net) {
8310 if (chk->
data == NULL) {
8329 if ((auth == NULL) &&
8336 if ((chk->
send_size <= (
int)(mtu - omtu)) ||
8352 if ((auth == NULL) &&
8366 if (outchain == NULL) {
8437 if (chk->
whoTo == NULL) {
8465 if (*now_filled == 0) {
8477 no_fragmentflg, 0, asconf,
8478 inp->sctp_lport, stcb->
rport,
8488 if (from_where == 0) {
8491 if (error == ENOBUFS) {
8495 if (error == EHOSTUNREACH) {
8513 outchain = endoutchain = NULL;
8517 *num_out += ctl_cnt;
8566 (max_send_per_dest > 0) &&
8581 if (data_auth_reqd && (auth == NULL)) {
8585 switch (((
struct sockaddr *)&net->
ro.
_l_addr)->sa_family) {
8609 (skip_data_for_this_net == 0)) ||
8611 TAILQ_FOREACH_SAFE(chk, &asoc->
send_queue, sctp_next, nchk) {
8612 if (no_data_chunks) {
8622 if ((chk->
whoTo != NULL) &&
8623 (chk->
whoTo != net)) {
8631 (chk->
whoTo == NULL)) {
8635 (chk->
whoTo == NULL)) {
8652 SCTP_PRINTF(
"Warning chunk of %d bytes > mtu:%d and yet PMTU disc missed\n",
8672 if (data_auth_reqd) {
8683 }
else if (override_ok) {
8700 if (outchain == NULL) {
8726 if ((to_out > mx_mtu) && no_fragmentflg) {
8728 panic(
"Exceeding mtu of %d out size is %d", mx_mtu, to_out);
8730 SCTP_PRINTF(
"Exceeding mtu of %d out size is %d\n",
8735 data_list[bundle_at++] = chk;
8758 if ((mtu == 0) || (r_mtu == 0) || (one_chunk)) {
8799 if (bundle_at || hbflag) {
8801 if (*now_filled == 0) {
8819 inp->sctp_lport, stcb->
rport,
8826 if (from_where == 0) {
8829 if (error == ENOBUFS) {
8833 if (error == EHOSTUNREACH) {
8857 *num_out += (ctl_cnt + bundle_at);
8863 if (*now_filled == 0) {
8871 data_list[0]->
do_rtt = 1;
8885 if (old_start_at == NULL) {
8886 old_start_at = start_at;
8887 start_at = TAILQ_FIRST(&asoc->
nets);
8889 goto again_one_more_time;
8899 if ((*num_out == 0) && (*reason_code == 0)) {
8917 struct mbuf *mat, *last_mbuf;
8923 if (op_err == NULL) {
8938 padding_length = chunk_length % 4;
8939 if (padding_length != 0) {
8940 padding_length = 4 - padding_length;
8942 if (padding_length != 0) {
8974 int offset,
int limit,
9007 if (at + plen > limit) {
9015 if ((pad = (plen % 4)) > 0) {
9023#ifdef SCTP_MBUF_LOGGING
9070 struct mbuf *outchain;
9078 outchain =
SCTP_M_COPYM(m, offset, chk_length, M_NOWAIT);
9079 if (outchain == NULL) {
9083#ifdef SCTP_MBUF_LOGGING
9091 if (chk_length % 4 != 0) {
9108 chk->
data = outchain;
9119 struct mbuf *cookie_ack;
9126 if (cookie_ack == NULL) {
9145 chk->
data = cookie_ack;
9166 struct mbuf *m_shutdown_ack;
9171 if (m_shutdown_ack == NULL) {
9190 chk->
data = m_shutdown_ack;
9209 struct mbuf *m_shutdown;
9225 if (m_shutdown == NULL) {
9244 chk->
data = m_shutdown;
9278 struct mbuf *m_asconf;
9291 if (m_asconf == NULL) {
9306 chk->
data = m_asconf;
9335 if (latest_ack == NULL) {
9369 if (ack->
data == NULL) {
9375 if (m_ack == NULL) {
9379#ifdef SCTP_MBUF_LOGGING
9416 int *cnt_out,
struct timeval *now,
int *now_filled,
int *fr_done,
int so_locked)
9432 struct mbuf *m, *endofchain;
9435 int no_fragmentflg, bundle_at, cnt_thru;
9437 int error, i, one_chunk, fwd_tsn, ctl_cnt, tmr_started;
9441 int override_ok = 1;
9442 int data_auth_reqd = 0;
9446 tmr_started = ctl_cnt = 0;
9451 endofchain = m = NULL;
9453#ifdef SCTP_AUDITING_ENABLED
9454 sctp_audit_log(0xC3, 1);
9490 if ((auth == NULL) &&
9494 &auth, &auth_offset,
9516 no_fragmentflg, 0, 0,
9522 if (error == ENOBUFS) {
9561#ifdef SCTP_AUDITING_ENABLED
9562 sctp_auditing(20, inp, stcb, NULL);
9565 TAILQ_FOREACH(chk, &asoc->
sent_queue, sctp_next) {
9570 if (chk->
data == NULL) {
9571 SCTP_PRINTF(
"TSN:%x chk->snd_count:%d chk->sent:%d can't retran - no data\n",
9577 struct mbuf *op_err;
9580 SCTP_SNPRINTF(msg,
sizeof(msg),
"TSN %8.8x retransmitted %d times, giving up",
9622 goto one_chunk_around;
9635#ifdef SCTP_AUDITING_ENABLED
9636 sctp_audit_log(0xC3, 2);
9664 if (data_auth_reqd && (auth == NULL)) {
9672 if (data_auth_reqd) {
9683 }
else if (override_ok) {
9705 data_list[bundle_at++] = chk;
9710 if (one_chunk == 0) {
9715 for (fwd = TAILQ_NEXT(chk, sctp_next); fwd != NULL; fwd = TAILQ_NEXT(fwd, sctp_next)) {
9720 if (fwd->
whoTo != net) {
9724 if (data_auth_reqd && (auth == NULL)) {
9729 if (data_auth_reqd) {
9740 }
else if (override_ok) {
9765 data_list[bundle_at++] = fwd;
9792 auth_offset, auth, auth_keyid,
9793 no_fragmentflg, 0, 0,
9800 if (error == ENOBUFS) {
9821 if (*now_filled == 0) {
9828 *cnt_out += bundle_at;
9829#ifdef SCTP_AUDITING_ENABLED
9830 sctp_audit_log(0xC4, bundle_at);
9835 for (i = 0; i < bundle_at; i++) {
9853 if (data_list[i]->book_size_scale) {
9865 atomic_add_int(&((asoc)->total_output_queue_size), data_list[i]->book_size);
9878 data_list[i]->whoTo->flight_size,
9892 if ((data_list[i] == TAILQ_FIRST(&asoc->
sent_queue)) &&
9893 (tmr_started == 0)) {
9912#ifdef SCTP_AUDITING_ENABLED
9913 sctp_auditing(21, inp, stcb, NULL);
9942 TAILQ_FOREACH(net, &asoc->
nets, sctp_next) {
9980 int error = 0, num_out, tot_out = 0, ret = 0, reason_code;
9981 unsigned int burst_cnt = 0;
9988 unsigned int tot_frs = 0;
10006 if ((un_sent <= 0) &&
10036 &now, &now_filled, frag_point, so_locked);
10061 &now, &now_filled, frag_point, so_locked);
10062#ifdef SCTP_AUDITING_ENABLED
10063 sctp_auditing(8, inp, stcb, NULL);
10073#ifdef SCTP_AUDITING_ENABLED
10074 sctp_auditing(9, inp, stcb, NULL);
10083#ifdef SCTP_AUDITING_ENABLED
10084 sctp_auditing(10, inp, stcb, NULL);
10088 &now, &now_filled, frag_point, so_locked);
10095 if ((num_out == 0) && (ret == 0)) {
10100#ifdef SCTP_AUDITING_ENABLED
10101 sctp_auditing(12, inp, stcb, NULL);
10104 TAILQ_FOREACH(net, &asoc->
nets, sctp_next) {
10151 &reason_code, 0, from_where,
10152 &now, &now_filled, frag_point, so_locked);
10166 tot_out += num_out;
10170 if (num_out == 0) {
10198 }
while (num_out &&
10201 (burst_cnt < asoc->max_burst)));
10240 struct sockaddr *addr,
10241 struct mbuf *control,
10256 (
struct uio *)NULL,
10272 unsigned int cnt_of_space, i, ovh;
10273 unsigned int space_needed;
10274 unsigned int cnt_of_skipped = 0;
10287 goto sctp_fill_in_rest;
10308 if (chk->
data == NULL) {
10323 TAILQ_FOREACH(at, &asoc->
sent_queue, sctp_next) {
10342 cnt_of_space = (
unsigned int)M_TRAILINGSPACE(chk->
data);
10355 0xff, 0, cnt_of_skipped,
10359 if (cnt_of_space < space_needed) {
10366 0xff, 0xff, cnt_of_space,
10381 for (i = 0; i < cnt_of_skipped; i++) {
10382 tp1 = TAILQ_NEXT(at, sctp_next);
10400 advance_peer_ack_point = last->
rec.
data.
tsn;
10447 TAILQ_FOREACH(at, &asoc->
sent_queue, sctp_next) {
10448 if (i >= cnt_of_skipped) {
10455 if (at->
rec.
data.
tsn == advance_peer_ack_point) {
10463 strseq_m->
flags = 0;
10496 int limit_reached = 0;
10497 unsigned int i, siz, j;
10498 unsigned int num_gap_blocks = 0, num_nr_gap_blocks = 0, space;
10512 asoc = &stcb->
asoc;
10528 a_chk->
data = NULL;
10530 if (a_chk->
whoTo) {
10532 a_chk->
whoTo = NULL;
10537 if (a_chk == NULL) {
10539 if (a_chk == NULL) {
10560 a_chk->
asoc = asoc;
10564 a_chk->
whoTo = NULL;
10572 if (a_chk->
whoTo == NULL) {
10579 if (a_chk->
whoTo) {
10596 space_req = MCLBYTES;
10600 if ((a_chk->
data == NULL) ||
10601 (a_chk->
whoTo == NULL)) {
10606 a_chk->
data = NULL;
10623 space = (
unsigned int)M_TRAILINGSPACE(a_chk->
data);
10627 limit = mtod(a_chk->
data, caddr_t);
10642#ifdef SCTP_ASOCLOG_OF_TSNS
10644 stcb->
asoc.cumack_log_atsnt++;
10646 stcb->
asoc.cumack_log_atsnt = 0;
10682 for (i = 0; i < siz; i++) {
10692 tsn_map &= (~0U << (1 - offset));
10719 gap_descriptor->
start = htons((selector->
gaps[j].
start + offset));
10721 gap_descriptor->
end = htons((selector->
gaps[j].
end + offset));
10734 if (limit_reached) {
10742 (limit_reached == 0)) {
10758 for (i = 0; i < siz; i++) {
10766 tsn_map &= (~0U << (1 - offset));
10774 num_nr_gap_blocks--;
10794 gap_descriptor->
start = htons((selector->
gaps[j].
start + offset));
10796 gap_descriptor->
end = htons((selector->
gaps[j].
end + offset));
10797 num_nr_gap_blocks++;
10809 if (limit_reached) {
10818 if ((limit_reached == 0) && (asoc->
numduptsns)) {
10824 if (((caddr_t)dup +
sizeof(
uint32_t)) > limit) {
10838 num_dups *
sizeof(int32_t));
10850 num_dups *
sizeof(int32_t));
10858 nr_sack->ch.chunk_type = type;
10859 nr_sack->ch.chunk_flags = flags;
10873 struct mbuf *m_abort, *m, *m_last;
10874 struct mbuf *m_out, *m_end = NULL;
10881 uint16_t cause_len, chunk_len, padding_len;
10897 if (m_abort == NULL) {
10918 padding_len =
SCTP_SIZE32(chunk_len) - chunk_len;
10919 if (m_out == NULL) {
10945 if (padding_len > 0) {
10946 if ((m_last == NULL) ||
10960 if (error == ENOBUFS) {
10976 struct mbuf *m_shutdown_comp;
10983 if (m_shutdown_comp == NULL) {
10987 if (reflect_vtag) {
11001 m_shutdown_comp, 0, NULL, 0, 1, 0, 0,
11008 if (error == ENOBUFS) {
11022 uint8_t type,
struct mbuf *cause,
11026 struct mbuf *o_pak;
11030#if defined(INET) || defined(INET6)
11033 int ret, len, cause_len, padding_len;
11039 struct sockaddr_in6 *src_sin6, *dst_sin6;
11045 if (cause != NULL) {
11046 struct mbuf *m_at, *m_last = NULL;
11053 padding_len = cause_len % 4;
11054 if (padding_len != 0) {
11055 padding_len = 4 - padding_len;
11057 if (padding_len != 0) {
11068 switch (dst->sa_family) {
11071 len +=
sizeof(
struct ip);
11076 len +=
sizeof(
struct ip6_hdr);
11082#if defined(INET) || defined(INET6)
11084 len +=
sizeof(
struct udphdr);
11088 if (mout == NULL) {
11097 M_SETFIB(mout, fibnum);
11098 mout->m_pkthdr.flowid = mflowid;
11099 M_HASHTYPE_SET(mout, mflowtype);
11106 switch (dst->sa_family) {
11111 ip = mtod(mout,
struct ip *);
11126 len =
sizeof(
struct ip);
11127 shout = (
struct sctphdr *)((caddr_t)
ip + len);
11132 src_sin6 = (
struct sockaddr_in6 *)src;
11133 dst_sin6 = (
struct sockaddr_in6 *)dst;
11134 ip6 = mtod(mout,
struct ip6_hdr *);
11135 ip6->ip6_flow = htonl(0x60000000);
11136 if (V_ip6_auto_flowlabel) {
11145 ip6->
ip6_src = dst_sin6->sin6_addr;
11146 ip6->
ip6_dst = src_sin6->sin6_addr;
11147 len =
sizeof(
struct ip6_hdr);
11148 shout = (
struct sctphdr *)((caddr_t)ip6 + len);
11153 shout = mtod(mout,
struct sctphdr *);
11156#if defined(INET) || defined(INET6)
11162 udp = (
struct udphdr *)shout;
11169 cause_len + padding_len));
11170 len +=
sizeof(
struct udphdr);
11171 shout = (
struct sctphdr *)((caddr_t)shout +
sizeof(
struct udphdr));
11180 shout->
v_tag = htonl(vtag);
11184 len +=
sizeof(
struct sctphdr);
11194 len += cause_len + padding_len;
11201 switch (dst->sa_family) {
11219 mout->m_pkthdr.csum_flags = CSUM_SCTP;
11220 mout->m_pkthdr.csum_data = offsetof(
struct sctphdr, checksum);
11223#ifdef SCTP_PACKET_LOGGING
11225 sctp_packet_log(o_pak);
11242 mout->m_pkthdr.csum_flags = CSUM_SCTP_IPV6;
11243 mout->m_pkthdr.csum_data = offsetof(
struct sctphdr, checksum);
11246#ifdef SCTP_PACKET_LOGGING
11248 sctp_packet_log(o_pak);
11282 mflowtype, mflowid, fibnum,
11291 struct timeval now;
11324 if (chk->
data == NULL) {
11410 ctsn = ntohl(ecne->
tsn);
11412 ecne->
tsn = htonl(high_tsn);
11434 if (chk->
data == NULL) {
11450 ecne->
tsn = htonl(high_tsn);
11458 struct mbuf *m,
int len,
int iphlen,
int bad_crc)
11469 unsigned int chk_length;
11474 asoc = &stcb->
asoc;
11496 offset = iphlen +
sizeof(
struct sctphdr);
11498 sizeof(*ch), (
uint8_t *)&chunk_buf);
11499 while (ch != NULL) {
11501 if (chk_length <
sizeof(*ch)) {
11522 sizeof(*ch), (
uint8_t *)&chunk_buf);
11536 if (chk->
data == NULL) {
11600 m_copydata(m, iphlen, len, (caddr_t)datap);
11626 ctsn = ntohl(cwr->
tsn);
11628 cwr->
tsn = htonl(high_tsn);
11648 if (chk->
data == NULL) {
11662 cwr->
tsn = htonl(high_tsn);
11675 int number_entries = 0;
11689 if (number_entries == 0) {
11693 number_entries = 0;
11705 if (number_entries) {
11713 if (at >= number_entries) {
11742 int number_entries,
uint16_t *list,
11759 if (number_entries) {
11760 for (i = 0; i < number_entries; i++) {
11847 asoc = &stcb->
asoc;
11872 if (chk->
data == NULL) {
12005 asoc = &stcb->
asoc;
12024 if (chk->
data == NULL) {
12050 m_freem(chk->
data);
12081 int can_send_out_req = 0;
12084 asoc = &stcb->
asoc;
12092 if ((send_in_req == 0) && (send_tsn_req == 0) &&
12093 (add_stream == 0)) {
12098 if (send_tsn_req && send_in_req) {
12102 }
else if (send_in_req) {
12103 can_send_out_req = 1;
12105 if (number_entries > (MCLBYTES -
12127 if (chk->
data == NULL) {
12150 if (can_send_out_req) {
12159 if ((add_stream & 1) &&
12165#if defined(SCTP_DETAILED_STR_STATS)
12179 x = add_stream & 0xfe;
12198#if defined(SCTP_DETAILED_STR_STATS)
12213 TAILQ_FOREACH_SAFE(sp, &oldstream[i].outqueue,
next, nsp) {
12214 TAILQ_REMOVE(&oldstream[i].outqueue, sp,
next);
12223#if defined(SCTP_DETAILED_STR_STATS)
12244 if ((add_stream & 1) && (adding_o > 0)) {
12251 if ((add_stream & 2) && (adding_i > 0)) {
12261 if (send_tsn_req) {
12291 mflowtype, mflowid, fibnum,
12303 mflowtype, mflowid, fibnum,
12308static struct mbuf *
12311 int user_marks_eor,
12314 struct mbuf **new_tail)
12318 m = m_uiotombuf(uio, M_WAITOK, max_send_len, 0,
12319 (M_PKTHDR | (user_marks_eor ? M_EOR : 0)));
12324 *sndout = m_length(m, NULL);
12325 *new_tail = m_last(m);
12335 sp->
data = m_uiotombuf(uio, M_WAITOK, sp->
length,
12337 if (sp->
data == NULL) {
12352 ssize_t max_send_len,
12353 int user_marks_eor,
12375 *error = ECONNRESET;
12396 ((user_marks_eor == 0) ||
12440 struct sockaddr *addr,
12443 struct mbuf *control,
12448 int error, use_sndinfo = 0;
12450 struct sockaddr *addr_to_use;
12451#if defined(INET) && defined(INET6)
12458 sizeof(sndrcvninfo))) {
12463 addr_to_use = addr;
12464#if defined(INET) && defined(INET6)
12465 if ((addr != NULL) && (addr->sa_family == AF_INET6)) {
12466 struct sockaddr_in6 *sin6;
12468 if (addr->sa_len !=
sizeof(
struct sockaddr_in6)) {
12472 sin6 = (
struct sockaddr_in6 *)addr;
12473 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
12474 in6_sin6_2_sin(&sin, sin6);
12475 addr_to_use = (
struct sockaddr *)&sin;
12482 use_sndinfo ? &sndrcvninfo : NULL
12490 struct sockaddr *addr,
12492 struct mbuf *i_pak,
12493 struct mbuf *control,
12500 struct epoch_tracker et;
12501 ssize_t sndlen = 0, max_len, local_add_more;
12503 struct mbuf *top = NULL;
12504 int queue_only = 0, queue_only_for_init = 0;
12505 bool free_cnt_applied =
false;
12507 int now_filled = 0;
12508 unsigned int inqueue_bytes = 0;
12512 struct timeval now;
12516 int user_marks_eor;
12517 bool create_lock_applied =
false;
12518 int nagle_applies = 0;
12519 int some_on_control = 0;
12520 int got_all_of_the_send = 0;
12521 bool hold_tcblock =
false;
12522 int non_blocking = 0;
12523 ssize_t local_soresv = 0;
12537 if (i_pak != NULL) {
12542 if ((uio == NULL) && (i_pak == NULL)) {
12547 atomic_add_int(&
inp->total_sends, 1);
12549 if (uio->uio_resid < 0) {
12553 sndlen = uio->uio_resid;
12572 if (addr != NULL) {
12575 switch (raddr->
sa.sa_family) {
12588 if (raddr->
sin6.sin6_len !=
sizeof(
struct sockaddr_in6)) {
12593 port = raddr->
sin6.sin6_port;
12598 error = EAFNOSUPPORT;
12605 if (srcv != NULL) {
12620 if (flags & MSG_EOR) {
12623 if (flags & MSG_EOF) {
12642 if (stcb != NULL) {
12644 hold_tcblock =
true;
12654 if (stcb != NULL) {
12656 hold_tcblock =
true;
12658 }
else if (addr != NULL) {
12668 if (stcb == NULL) {
12674 hold_tcblock =
true;
12678 if (stcb != NULL) {
12680 KASSERT(hold_tcblock, (
"tcb lock hold, hold_tcblock is false"));
12682 KASSERT(!hold_tcblock, (
"hold_tcblock is true, but stcb is NULL"));
12685 if ((stcb == NULL) && (addr != NULL)) {
12688 create_lock_applied =
true;
12697 (addr->sa_family == AF_INET6)) {
12707#if defined(INET) || defined(INET6)
12708 if ((stcb == NULL) && (control != NULL) && (port > 0)) {
12709 stcb = sctp_findassociation_cmsgs(&t_inp, port, control, &net, &error);
12712 if (stcb == NULL) {
12718 hold_tcblock =
true;
12720 create_lock_applied =
false;
12725 if (t_inp != inp) {
12731 if (stcb == NULL) {
12732 if (addr == NULL) {
12741 ((sinfo_flags &
SCTP_EOF) && (sndlen == 0))) {
12752 KASSERT(create_lock_applied, (
"create_lock_applied is false"));
12758 if (stcb == NULL) {
12763 hold_tcblock =
true;
12765 create_lock_applied =
false;
12773 if (control != NULL) {
12777 hold_tcblock =
false;
12783 queue_only_for_init = 1;
12793 KASSERT(!create_lock_applied, (
"create_lock_applied is true"));
12794 KASSERT(stcb != NULL, (
"stcb is NULL"));
12795 KASSERT(hold_tcblock, (
"hold_tcblock is false"));
12797 asoc = &stcb->
asoc;
12799 (
"Association about to be freed"));
12801 atomic_add_int(&asoc->
refcnt, 1);
12802 free_cnt_applied =
true;
12804 if (srcv == NULL) {
12807 if (flags & MSG_EOR) {
12810 if (flags & MSG_EOF) {
12819 if ((net == NULL) ||
12820 ((port != 0) && (port != stcb->
rport))) {
12842 || (flags & (MSG_NBIO | MSG_DONTWAIT)) != 0
12847 if (non_blocking) {
12851 if (user_marks_eor == 0) {
12862 error = EWOULDBLOCK;
12869 local_soresv = sndlen;
12872 error = ECONNRESET;
12912 error = ECONNRESET;
12918 p->td_ru.ru_msgsnd++;
12921 KASSERT(stcb != NULL, (
"stcb is NULL"));
12922 KASSERT(hold_tcblock, (
"hold_tcblock is false"));
12925 (
"Association about to be freed"));
12931 ssize_t tot_demand, tot_out = 0, max_out;
12970 if (tot_out > max_out) {
12980 hold_tcblock =
false;
12981 error = uiomove((caddr_t)ph, (
int)tot_out, uio);
12983 hold_tcblock =
true;
13002 atomic_subtract_int(&asoc->
refcnt, 1);
13003 free_cnt_applied =
false;
13005 NET_EPOCH_ENTER(et);
13007 NET_EPOCH_EXIT(et);
13020 KASSERT(stcb != NULL, (
"stcb is NULL"));
13021 KASSERT(hold_tcblock, (
"hold_tcblock is false"));
13024 (
"Association about to be freed"));
13034 if ((user_marks_eor == 0) &&
13041 if ((uio == NULL) && user_marks_eor) {
13051 if (user_marks_eor) {
13058 local_add_more = sndlen;
13060 if (non_blocking) {
13061 goto skip_preblock;
13063 if (((max_len <= local_add_more) &&
13068 SOCKBUF_LOCK(&so->so_snd);
13085 hold_tcblock =
false;
13086 error = sbwait(&so->so_snd);
13088 hold_tcblock =
true;
13090 SOCKBUF_UNLOCK(&so->so_snd);
13094 if (error || so->so_error || be.
error) {
13097 error = so->so_error;
13102 SOCKBUF_UNLOCK(&so->so_snd);
13116 SOCKBUF_UNLOCK(&so->so_snd);
13120 KASSERT(stcb != NULL, (
"stcb is NULL"));
13121 KASSERT(hold_tcblock, (
"hold_tcblock is false"));
13124 (
"Association about to be freed"));
13132 got_all_of_the_send = 1;
13150 hold_tcblock =
false;
13163 sp =
sctp_copy_it_in(stcb, asoc, srcv, uio, net, max_len, user_marks_eor, &error);
13194 sp = TAILQ_LAST(&strm->
outqueue, sctp_streamhead);
13198 panic(
"Warning: Last msg marked incomplete, yet nothing left?");
13200 SCTP_PRINTF(
"Warning: Last msg marked incomplete, yet nothing left?\n");
13215 while (uio->uio_resid > 0) {
13217 struct mbuf *new_tail, *mm;
13227 (uio->uio_resid && (uio->uio_resid <= max_len))) {
13230 if (hold_tcblock) {
13232 hold_tcblock =
false;
13234 mm =
sctp_copy_resume(uio, (
int)max_len, user_marks_eor, &error, &sndout, &new_tail);
13235 if ((mm == NULL) || error) {
13259 error = ECONNRESET;
13274 atomic_add_int(&sp->
length, sndout);
13280 if ((uio->uio_resid == 0) &&
13281 ((user_marks_eor == 0) ||
13283 (user_marks_eor && (sinfo_flags &
SCTP_EOR)))) {
13290 if (uio->uio_resid == 0) {
13300 if (!hold_tcblock) {
13302 hold_tcblock =
true;
13314 hold_tcblock =
false;
13317 if (non_blocking) {
13324 if (!hold_tcblock) {
13326 hold_tcblock =
true;
13331 if (queue_only_for_init) {
13332 if (!hold_tcblock) {
13334 hold_tcblock =
true;
13340 NET_EPOCH_ENTER(et);
13342 NET_EPOCH_EXIT(et);
13383 nagle_applies, un_sent);
13388 if (queue_only_for_init)
13389 queue_only_for_init = 0;
13390 if ((queue_only == 0) && (nagle_applies == 0)) {
13398 NET_EPOCH_ENTER(et);
13399 if (!hold_tcblock) {
13401 hold_tcblock =
true;
13411 NET_EPOCH_EXIT(et);
13413 if (hold_tcblock) {
13415 hold_tcblock =
false;
13417 SOCKBUF_LOCK(&so->so_snd);
13437 asoc, uio->uio_resid);
13441 error = sbwait(&so->so_snd);
13444 if (error || so->so_error || be.
error) {
13447 error = so->so_error;
13452 SOCKBUF_UNLOCK(&so->so_snd);
13468 SOCKBUF_UNLOCK(&so->so_snd);
13502 if (uio->uio_resid == 0) {
13503 got_all_of_the_send = 1;
13505 if (!hold_tcblock) {
13507 hold_tcblock =
true;
13514 got_all_of_the_send = 1;
13522 KASSERT(stcb != NULL, (
"stcb is NULL"));
13523 KASSERT(hold_tcblock, (
"hold_tcblock is false"));
13526 (
"Association about to be freed"));
13530 (got_all_of_the_send == 1)) {
13583 struct mbuf *op_err;
13587 if (free_cnt_applied) {
13588 atomic_subtract_int(&asoc->
refcnt, 1);
13589 free_cnt_applied =
false;
13592 "%s:%d at %s", __FILE__, __LINE__, __func__);
13595 NET_EPOCH_ENTER(et);
13598 NET_EPOCH_EXIT(et);
13599 hold_tcblock =
false;
13611 KASSERT(stcb != NULL, (
"stcb is NULL"));
13612 KASSERT(hold_tcblock, (
"hold_tcblock is false"));
13615 (
"Association about to be freed"));
13618 some_on_control = 1;
13620 if (queue_only_for_init) {
13625 NET_EPOCH_ENTER(et);
13627 NET_EPOCH_EXIT(et);
13668 nagle_applies, un_sent);
13673 NET_EPOCH_ENTER(et);
13674 if ((queue_only == 0) && (nagle_applies == 0) && (asoc->
peers_rwnd && un_sent)) {
13676 }
else if ((queue_only == 0) &&
13681 }
else if (some_on_control) {
13682 int num_out, reason;
13686 &reason, 1, 1, &now, &now_filled,
13690 NET_EPOCH_EXIT(et);
13696 KASSERT(stcb != NULL, (
"stcb is NULL"));
13697 KASSERT(hold_tcblock, (
"hold_tcblock is false"));
13702 if (create_lock_applied) {
13705 if (stcb != NULL) {
13706 if (local_soresv) {
13707 atomic_subtract_int(&asoc->
sb_send_resv, (
int)sndlen);
13709 if (hold_tcblock) {
13712 if (free_cnt_applied) {
13713 atomic_subtract_int(&asoc->
refcnt, 1);
13716 if (mtx_owned(&stcb->
tcb_mtx)) {
13717 panic(
"Leaving with tcb mtx owned?");
13720 panic(
"Leaving with tcb send mtx owned?");
13727 if (control != NULL) {
13741 struct mbuf *m_auth;
13746 if ((m_end == NULL) || (auth_ret == NULL) || (offset == NULL) ||
13758 if (m_auth == NULL) {
13767 memset(auth, 0,
sizeof(*auth));
13770 chunk_len =
sizeof(*auth) +
13785 if (auth_ret != NULL)
13795 struct nd_prefix *pfx = NULL;
13796 struct nd_pfxrouter *pfxrtr = NULL;
13797 struct sockaddr_in6 gw6;
13799 if (ro == NULL || ro->ro_nh == NULL || src6->sin6_family != AF_INET6)
13805 if (pfx->ndpr_stateflags & NDPRF_DETACHED)
13807 if (IN6_ARE_MASKED_ADDR_EQUAL(&pfx->ndpr_prefix.sin6_addr,
13808 &src6->sin6_addr, &pfx->ndpr_mask))
13823 LIST_FOREACH(pfxrtr, &pfx->ndpr_advrtrs, pfr_entry) {
13824 memset(&gw6, 0,
sizeof(
struct sockaddr_in6));
13825 gw6.sin6_family = AF_INET6;
13826 gw6.sin6_len =
sizeof(
struct sockaddr_in6);
13827 memcpy(&gw6.sin6_addr, &pfxrtr->router->rtaddr,
13828 sizeof(
struct in6_addr));
13833 if (
sctp_cmpaddr((
struct sockaddr *)&gw6, &ro->ro_nh->gw_sa)) {
13850 struct ifaddr *ifa;
13851 struct in_addr srcnetaddr, gwnetaddr;
13853 if (ro == NULL || ro->ro_nh == NULL ||
13854 sifa->
address.
sa.sa_family != AF_INET) {
13857 ifa = (
struct ifaddr *)sifa->
ifa;
13865 sin = &ro->ro_nh->gw4_sa;
__sa_family_t sa_family_t
u_short in_pseudo(u_int32_t a, u_int32_t b, u_int32_t c)
const struct encaptab * cookie
int prison_check_ip4(const struct ucred *cred, const struct in_addr *ia)
#define IPV6_FLOWLABEL_MASK
void ip_fillid(struct ip *ip)
#define SCTP_PCB_FLAGS_SND_ITERATOR_UP
#define SCTP_DATA_FIRST_FRAG
#define SCTP_INITIATION_ACK
#define SCTP_FLIGHT_LOGGING_ENABLE
#define SCTP_HEARTBEAT_ACK
#define SCTP_PCB_FLAGS_BOUND_V6
#define SCTP_LOG_AT_SEND_2_OUTQ
#define SCTP_PCB_FLAGS_TCPTYPE
#define SCTP_PCB_FLAGS_SOCKET_ALLGONE
#define SCTP_FORWARD_CUM_TSN
#define SCTP_OPERATION_ERROR
#define SCTP_DATA_UNORDERED
#define SCTP_NAGLE_LOGGING_ENABLE
#define SCTP_PACKET_DROPPED
#define SCTP_LOG_TRY_ADVANCE
#define SCTP_SELECTIVE_ACK
#define SCTP_PCB_FLAGS_NODELAY
#define SCTP_LOG_MAXBURST_ENABLE
#define SCTP_BLK_LOGGING_ENABLE
#define SCTP_MOBILITY_BASE
#define SCTP_PCB_FLAGS_IN_TCPPOOL
#define SCTP_CAUSE_UNRESOLVABLE_ADDR
#define SCTP_PCB_FLAGS_SOCKET_GONE
#define SCTP_DATA_NOT_FRAG
#define SCTP_CAUSE_PROTOCOL_VIOLATION
#define SCTP_PCB_FLAGS_EXPLICIT_EOR
#define SCTP_STREAM_RESET
#define SCTP_DATA_LAST_FRAG
#define SCTP_LOG_RWND_ENABLE
#define SCTP_PCB_FLAGS_CONNECTED
#define SCTP_AUTHENTICATION
#define SCTP_DATA_SACK_IMMEDIATELY
#define SCTP_SHUTDOWN_ACK
#define SCTP_SHUTDOWN_COMPLETE
#define SCTP_CAUSE_USER_INITIATED_ABT
#define SCTP_MBUF_LOGGING_ENABLE
#define SCTP_CWND_LOGGING_ENABLE
#define SCTP_CWR_REDUCE_OVERRIDE
#define SCTP_ABORT_ASSOCIATION
#define SCTP_PCB_FLAGS_NO_FRAGMENT
#define SCTP_HEARTBEAT_REQUEST
#define SCTP_NR_SELECTIVE_ACK
#define SCTP_PACKET_TRUNCATED
#define SCTP_LAST_PACKET_TRACING
#define SCTP_PCB_FLAGS_MULTIPLE_ASCONFS
#define SCTP_PCB_FLAGS_BOUNDALL
#define SCTP_IFORWARD_CUM_TSN
int sctp_is_addr_pending(struct sctp_tcb *stcb, struct sctp_ifa *sctp_ifa)
struct mbuf * sctp_compose_asconf(struct sctp_tcb *stcb, int *retlen, int addr_locked)
int sctp_serialize_auth_chunks(const sctp_auth_chklist_t *list, uint8_t *ptr)
uint32_t sctp_get_hmac_digest_len(uint16_t hmac_algo)
size_t sctp_auth_get_chklist_size(const sctp_auth_chklist_t *list)
int sctp_serialize_hmaclist(sctp_hmaclist_t *list, uint8_t *ptr)
void sctp_auth_key_acquire(struct sctp_tcb *stcb, uint16_t key_id)
void sctp_fill_hmac_digest_m(struct mbuf *m, uint32_t auth_offset, struct sctp_auth_chunk *auth, struct sctp_tcb *stcb, uint16_t keyid)
uint32_t sctp_get_auth_chunk_len(uint16_t hmac_algo)
uint32_t sctp_hmac_m(uint16_t hmac_algo, uint8_t *key, uint32_t keylen, struct mbuf *m, uint32_t m_offset, uint8_t *digest, uint32_t trailer)
#define SCTP_AUTH_RANDOM_SIZE_DEFAULT
#define sctp_auth_is_required_chunk(chunk, list)
struct mbuf * sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header, int how, int allonebuf, int type)
#define SCTP_STR_RESET_OUT_REQUEST
#define IN4_ISPRIVATE_ADDRESS(a)
#define SCTP_BLOCK_LOG_INTO_BLK
#define SCTP_DIAG_INFO_LEN
#define SCTP_DEBUG_OUTPUT1
#define SCTP_SUPPORTED_CHUNK_EXT
#define SCTP_NAGLE_APPLIED
#define SCTP_FIRST_MBUF_RESV
#define SCTP_STATE_COOKIE_ECHOED
#define SCTP_ADD_IP_ADDRESS
#define SCTP_DATAGRAM_NR_ACKED
#define SCTP_HAS_NAT_SUPPORT
#define SCTP_STATE_WAS_ABORTED
#define SCTP_PRSCTP_SUPPORTED
#define SCTP_BLOCK_LOG_INTO_BLKA
#define SCTP_ULP_ADAPTATION
#define SCTP_ADD_SUBSTATE(_stcb, _substate)
#define SCTP_TSN_GT(a, b)
#define SCTP_MAX_BURST_APPLIED
#define SCTP_OUTPUT_FROM_T3
#define SCTP_HOSTNAME_ADDRESS
#define SCTP_VERSION_STRING
#define SCTP_DATAGRAM_RESEND
#define SCTP_DEBUG_OUTPUT4
#define SCTP_FWD_TSN_CHECK
#define SCTP_SUCCESS_REPORT
#define SCTP_SO_NOT_LOCKED
#define SCTP_CWNDLOG_PRESEND
#define SCTP_OUTPUT_FROM_USR_SEND
#define SCTP_OUTPUT_FROM_COOKIE_ACK
#define SCTP_DEL_IP_ADDRESS
#define SCTP_STATE_COOKIE
#define SCTP_DEFAULT_ADD_MORE
#define SCTP_SIGNATURE_SIZE
#define SCTP_TIMER_TYPE_INIT
#define SCTP_STR_RESET_IN_REQUEST
#define SCTP_CWND_LOG_FROM_SEND
#define SCTP_SEND_NOW_COMPLETES
#define SCTP_MAX_DATA_BUNDLING
#define SCTP_ADDR_NO_PMTUD
#define IN4_ISLOOPBACK_ADDRESS(a)
#define SCTP_STATE_SHUTDOWN_PENDING
#define SCTP_NAGLE_SKIPPED
#define SCTP_ADDR_UNCONFIRMED
#define SCTP_FLIGHT_LOG_UP
#define SCTP_TIMER_TYPE_STRRESET
#define SCTP_DECREASE_PEER_RWND
#define SCTP_TIMER_TYPE_RECV
#define SCTP_DONOT_SETSCOPE
#define SCTP_FROM_SCTP_OUTPUT
#define SCTP_RECV_BUFFER_SPLITTING
#define SCTP_STATE_SHUTDOWN_ACK_SENT
#define PR_SCTP_UNORDERED_FLAG
#define SCTP_TIMER_TYPE_SHUTDOWNGUARD
#define SCTP_GET_STATE(_stcb)
#define SCTP_ADDR_IS_CONFIRMED
#define SCTP_GETTIME_TIMEVAL(x)
#define SCTP_STR_RESET_ADD_IN_STREAMS
#define SCTP_DATAGRAM_UNSENT
#define SCTP_OUTPUT_FROM_HB_TMR
#define SCTP_DEBUG_OUTPUT3
#define SCTP_COOKIE_PRESERVE
#define SCTP_MAX_CHUNK_LENGTH
#define SCTP_IPV4_ADDRESS
#define SCTP_STATE_COOKIE_WAIT
#define SCTP_DATAGRAM_SENT
#define SCTP_TIMER_TYPE_SHUTDOWN
#define SCTP_ADDR_OUT_OF_SCOPE
#define SCTP_STATE_SHUTDOWN_SENT
#define SCTP_STR_RESET_TSN_REQUEST
#define SCTP_STATE_SHUTDOWN_RECEIVED
#define SCTP_SET_PRIM_ADDR
#define SCTP_CWND_LOG_FILL_OUTQ_CALLED
#define SCTP_STR_RESET_ADD_OUT_STREAMS
#define SCTP_BLOCK_LOG_OUTOF_BLK
#define SCTP_STATE_ABOUT_TO_BE_FREED
#define SCTP_IPV6_ADDRESS
#define SCTP_ADDR_REACHABLE
#define SCTP_NOTIFY_INTERFACE_DOWN
#define SCTP_ADDRESS_LIMIT
#define SCTP_CWND_LOG_FROM_RESEND
#define SCTP_SET_STATE(_stcb, _state)
#define SCTP_DEBUG_USRREQ1
#define SCTP_MAX_BURST_ERROR_STOP
#define SCTP_TIMER_TYPE_ASCONF
#define SCTP_STR_RESET_RESPONSE
#define SCTP_ERROR_CAUSE_IND
#define SCTP_FORWARD_TSN_SKIP
#define SCTP_SUPPORTED_ADDRTYPE
#define SCTP_TIMER_TYPE_SEND
#define SCTP_HEARTBEAT_INFO
#define SCTP_FLIGHT_LOG_UP_RSND
#define SCTP_SEND_BUFFER_SPLITTING
#define SCTP_MINIMAL_RWND
#define SCTP_UNRECOG_PARAM
#define SCTP_TIMER_TYPE_COOKIE
#define SCTP_STATE_PARTIAL_MSG_LEFT
#define SCTP_STRMOUT_LOG_SEND
#define SCTP_DEBUG_OUTPUT2
uint32_t sctp_calculate_cksum(struct mbuf *m, int32_t offset)
void sctp_set_rwnd(struct sctp_tcb *stcb, struct sctp_association *asoc)
void sctp_slide_mapping_arrays(struct sctp_tcb *stcb)
#define SCTP_PROBE5(probe, arg0, arg1, arg2, arg3, arg4)
#define SCTP_TCB_LOCK(_tcb)
#define SCTP_IPI_ADDR_RLOCK()
#define SCTP_INP_RLOCK(_inp)
#define SCTP_INP_INFO_RLOCK()
#define SCTP_ASOC_CREATE_UNLOCK(_inp)
#define SCTP_IPI_ADDR_RUNLOCK()
#define SCTP_INP_WUNLOCK(_inp)
#define SCTP_TCB_TRYLOCK(_tcb)
#define SCTP_TCB_SEND_UNLOCK(_tcb)
#define SCTP_INP_DECR_REF(_inp)
#define SCTP_INP_INFO_RUNLOCK()
#define SCTP_INP_WLOCK(_inp)
#define SCTP_TCB_LOCK_ASSERT(_tcb)
#define SCTP_INP_INCR_REF(_inp)
#define SCTP_TCB_UNLOCK(_tcb)
#define SCTP_ASOC_CREATE_LOCK(_inp)
#define SCTP_TCB_SEND_LOCK(_tcb)
#define SCTP_INP_RUNLOCK(_inp)
#define SCTP_LTRACE_ERR_RET(inp, stcb, net, file, err)
#define SCTP_LTRACE_ERR_RET_PKT(m, inp, stcb, net, file, err)
#define SCTP_IFN_IS_IFT_LOOP(ifn)
#define SCTP_BUF_AT(m, size)
#define SCTP_GET_IFN_VOID_FROM_ROUTE(ro)
#define SCTP_GET_HEADER_FOR_OUTPUT(o_pak)
#define MODULE_GLOBAL(__SYMBOL)
#define SCTP_HEADER_TO_CHAIN(m)
#define SCTP_SNPRINTF(...)
#define SCTP_ENABLE_UDP_CSUM(m)
#define SCTP_OS_TIMER_PENDING
struct route sctp_route_t
#define SCTP_BUF_RESV_UF(m, size)
#define SCTP_GET_IF_INDEX_FROM_ROUTE(ro)
#define SCTP_READ_RANDOM(buf, len)
#define SCTP_MALLOC(var, type, size, name)
#define SCTP_IPV6_V6ONLY(sctp_inpcb)
#define SCTP_RELEASE_PKT(m)
#define SCTP_PRINTF(params...)
#define SCTP_ATTACH_CHAIN(pak, m, packet_length)
#define SCTP_RTALLOC(ro, vrf_id, fibnum)
#define SCTP_ALIGN_TO_END(m, len)
#define SCTP_ROUTE_IS_REAL_LOOP(ro)
#define SCTP_GATHER_MTU_FROM_ROUTE(sctp_ifa, sa, nh)
#define SCTP_GET_HLIM(inp, ro)
#define SCTP_FREE(var, type)
#define SCTP_BUF_IS_EXTENDED(m)
#define SCTP_HEADER_LEN(m)
#define SCTPDBG(level, params...)
#define SCTP_SO_IS_NBIO(so)
#define SCTP_IP_OUTPUT(result, o_pak, ro, _inp, vrf_id)
#define SCTP_IS_LISTENING(inp)
#define SCTP_BASE_SYSCTL(__m)
#define SCTPDBG_ADDR(level, addr)
#define SCTP_SB_LIMIT_RCV(so)
#define SCTP_BUF_NEXT_PKT(m)
#define SCTP_IP6_OUTPUT(result, o_pak, ro, ifp, _inp, vrf_id)
#define SCTP_SB_LIMIT_SND(so)
static int sctp_find_cmsg(int c_type, void *data, struct mbuf *control, size_t cpsize)
static void sctp_add_stream_reset_in(struct sctp_tmit_chunk *chk, int number_entries, uint16_t *list, uint32_t seq)
static uint32_t sctp_move_to_outqueue(struct sctp_tcb *stcb, struct sctp_nets *net, struct sctp_stream_out *strq, uint32_t space_left, uint32_t frag_point, int *giveup, int eeor_mode, int *bail, int so_locked)
int sctp_is_addr_restricted(struct sctp_tcb *stcb, struct sctp_ifa *ifa)
void sctp_send_shutdown_complete(struct sctp_tcb *stcb, struct sctp_nets *net, int reflect_vtag)
int sctp_lower_sosend(struct socket *so, struct sockaddr *addr, struct uio *uio, struct mbuf *i_pak, struct mbuf *control, int flags, struct sctp_sndrcvinfo *srcv, struct thread *p)
static int sctp_chunk_retransmission(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sctp_association *asoc, int *cnt_out, struct timeval *now, int *now_filled, int *fr_done, int so_locked)
void sctp_send_shutdown_ack(struct sctp_tcb *stcb, struct sctp_nets *net)
static int sctp_msg_append(struct sctp_tcb *stcb, struct sctp_nets *net, struct mbuf *m, struct sctp_sndrcvinfo *srcv, int hold_stcb_lock)
int sctp_send_cookie_echo(struct mbuf *m, int offset, int limit, struct sctp_tcb *stcb, struct sctp_nets *net)
static struct mbuf * sctp_copy_out_all(struct uio *uio, ssize_t len)
void sctp_send_cookie_ack(struct sctp_tcb *stcb)
static struct sctp_ifa * sctp_choose_boundspecific_inp(struct sctp_inpcb *inp, sctp_route_t *ro, uint32_t vrf_id, int non_asoc_addr_ok, uint8_t dest_is_priv, uint8_t dest_is_loop, sa_family_t fam)
static struct mbuf * sctp_add_addr_to_mbuf(struct mbuf *m, struct sctp_ifa *ifa, uint16_t *len)
static int sctp_med_chunk_output(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sctp_association *asoc, int *num_out, int *reason_code, int control_only, int from_where, struct timeval *now, int *now_filled, uint32_t frag_point, int so_locked)
static int sctp_lowlevel_chunk_output(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sctp_nets *net, struct sockaddr *to, struct mbuf *m, uint32_t auth_offset, struct sctp_auth_chunk *auth, uint16_t auth_keyid, int nofragment_flag, int ecn_ok, int out_of_asoc_ok, uint16_t src_port, uint16_t dest_port, uint32_t v_tag, uint16_t port, union sctp_sockstore *over_addr, uint8_t mflowtype, uint32_t mflowid, int so_locked)
int sctp_v4src_match_nexthop(struct sctp_ifa *sifa, sctp_route_t *ro)
void sctp_send_cwr(struct sctp_tcb *stcb, struct sctp_nets *net, uint32_t high_tsn, uint8_t override)
uint32_t sctp_get_frag_point(struct sctp_tcb *stcb)
static void sctp_add_stream_reset_tsn(struct sctp_tmit_chunk *chk, uint32_t seq)
struct mbuf * sctp_add_auth_chunk(struct mbuf *m, struct mbuf **m_end, struct sctp_auth_chunk **auth_ret, uint32_t *offset, struct sctp_tcb *stcb, uint8_t chunk)
static struct sctp_ifa * sctp_select_nth_preferred_addr_from_ifn_boundall(struct sctp_ifn *ifn, struct sctp_inpcb *inp, struct sctp_tcb *stcb, int non_asoc_addr_ok, uint8_t dest_is_loop, uint8_t dest_is_priv, int addr_wanted, sa_family_t fam, sctp_route_t *ro)
static void sctp_set_prsctp_policy(struct sctp_stream_queue_pending *sp)
int sctp_output(struct sctp_inpcb *inp, struct mbuf *m, struct sockaddr *addr, struct mbuf *control, struct thread *p, int flags)
void send_forward_tsn(struct sctp_tcb *stcb, struct sctp_association *asoc)
static struct mbuf * sctp_copy_mbufchain(struct mbuf *clonechain, struct mbuf *outchain, struct mbuf **endofchain, int can_take_mbuf, int sizeofcpy, uint8_t copy_by_ref)
struct mbuf * sctp_add_addresses_to_i_ia(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sctp_scoping *scope, struct mbuf *m_at, int cnt_inits_to, uint16_t *padding_len, uint16_t *chunk_len)
struct sctp_ifa * sctp_source_address_selection(struct sctp_inpcb *inp, struct sctp_tcb *stcb, sctp_route_t *ro, struct sctp_nets *net, int non_asoc_addr_ok, uint32_t vrf_id)
const struct sack_track sack_array[256]
static struct sctp_ifa * sctp_choose_boundspecific_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb, sctp_route_t *ro, uint32_t vrf_id, uint8_t dest_is_priv, uint8_t dest_is_loop, int non_asoc_addr_ok, sa_family_t fam)
void sctp_add_stream_reset_result_tsn(struct sctp_tmit_chunk *chk, uint32_t resp_seq, uint32_t result, uint32_t send_una, uint32_t recv_next)
static void sctp_sendall_iterator(struct sctp_inpcb *inp, struct sctp_tcb *stcb, void *ptr, uint32_t val SCTP_UNUSED)
static void sctp_prune_prsctp(struct sctp_tcb *stcb, struct sctp_association *asoc, struct sctp_sndrcvinfo *srcv, int dataout)
static struct sctp_ifa * sctp_is_ifa_addr_acceptable(struct sctp_ifa *ifa, uint8_t dest_is_loop, uint8_t dest_is_priv, sa_family_t fam)
void sctp_toss_old_cookies(struct sctp_tcb *stcb, struct sctp_association *asoc)
void sctp_queue_op_err(struct sctp_tcb *stcb, struct mbuf *op_err)
struct mbuf * sctp_arethere_unrecognized_parameters(struct mbuf *in_initpkt, int param_offset, int *abort_processing, struct sctp_chunkhdr *cp, int *nat_friendly, int *cookie_found)
static void sctp_fill_outqueue(struct sctp_tcb *stcb, struct sctp_nets *net, uint32_t frag_point, int eeor_mode, int *quit_now, int so_locked)
static int sctp_copy_one(struct sctp_stream_queue_pending *sp, struct uio *uio, int resv_upfront)
static int sctp_sendall(struct sctp_inpcb *inp, struct uio *uio, struct mbuf *m, struct sctp_sndrcvinfo *srcv)
void sctp_send_packet_dropped(struct sctp_tcb *stcb, struct sctp_nets *net, struct mbuf *m, int len, int iphlen, int bad_crc)
int sctp_send_str_reset_req(struct sctp_tcb *stcb, uint16_t number_entries, uint16_t *list, uint8_t send_in_req, uint8_t send_tsn_req, uint8_t add_stream, uint16_t adding_o, uint16_t adding_i, uint8_t peer_asked)
static int sctp_add_stream_reset_out(struct sctp_tcb *stcb, struct sctp_tmit_chunk *chk, uint32_t seq, uint32_t resp_seq, uint32_t last_sent)
static struct mbuf * sctp_copy_resume(struct uio *uio, int max_send_len, int user_marks_eor, int *error, uint32_t *sndout, struct mbuf **new_tail)
int sctp_is_address_in_scope(struct sctp_ifa *ifa, struct sctp_scoping *scope, int do_update)
static struct sctp_ifa * sctp_is_ifa_addr_preferred(struct sctp_ifa *ifa, uint8_t dest_is_loop, uint8_t dest_is_priv, sa_family_t fam)
void sctp_send_hb(struct sctp_tcb *stcb, struct sctp_nets *net, int so_locked)
void sctp_send_initiate_ack(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sctp_nets *src_net, struct mbuf *init_pkt, int iphlen, int offset, struct sockaddr *src, struct sockaddr *dst, struct sctphdr *sh, struct sctp_init_chunk *init_chk, uint8_t mflowtype, uint32_t mflowid, uint32_t vrf_id, uint16_t port)
static struct sctp_stream_queue_pending * sctp_copy_it_in(struct sctp_tcb *stcb, struct sctp_association *asoc, struct sctp_sndrcvinfo *srcv, struct uio *uio, struct sctp_nets *net, ssize_t max_send_len, int user_marks_eor, int *error)
void sctp_fix_ecn_echo(struct sctp_association *asoc)
void sctp_send_initiate(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int so_locked)
void sctp_send_asconf(struct sctp_tcb *stcb, struct sctp_nets *net, int addr_locked)
void sctp_toss_old_asconf(struct sctp_tcb *stcb)
static uint32_t sctp_can_we_split_this(struct sctp_tcb *stcb, uint32_t length, uint32_t space_left, uint32_t frag_point, int eeor_on)
void sctp_send_deferred_reset_response(struct sctp_tcb *stcb, struct sctp_stream_reset_list *ent, int response)
void sctp_add_stream_reset_result(struct sctp_tmit_chunk *chk, uint32_t resp_seq, uint32_t result)
void sctp_move_chunks_from_net(struct sctp_tcb *stcb, struct sctp_nets *net)
static void sctp_clean_up_ctl(struct sctp_tcb *stcb, struct sctp_association *asoc, int so_locked)
static void sctp_clean_up_datalist(struct sctp_tcb *stcb, struct sctp_association *asoc, struct sctp_tmit_chunk **data_list, int bundle_at, struct sctp_nets *net)
int sctp_is_addr_in_ep(struct sctp_inpcb *inp, struct sctp_ifa *ifa)
void sctp_send_sack(struct sctp_tcb *stcb, int so_locked)
void sctp_send_operr_to(struct sockaddr *src, struct sockaddr *dst, struct sctphdr *sh, uint32_t vtag, struct mbuf *cause, uint8_t mflowtype, uint32_t mflowid, uint16_t fibnum, uint32_t vrf_id, uint16_t port)
void sctp_send_heartbeat_ack(struct sctp_tcb *stcb, struct mbuf *m, int offset, int chk_length, struct sctp_nets *net)
static int sctp_count_num_preferred_boundall(struct sctp_ifn *ifn, struct sctp_inpcb *inp, struct sctp_tcb *stcb, int non_asoc_addr_ok, uint8_t dest_is_loop, uint8_t dest_is_priv, sa_family_t fam)
static int sctp_process_cmsgs_for_init(struct sctp_tcb *stcb, struct mbuf *control, int *error)
static uint8_t sctp_get_ect(struct sctp_tcb *stcb)
#define SCTP_MAX_GAPS_INARRAY
int sctp_sosend(struct socket *so, struct sockaddr *addr, struct uio *uio, struct mbuf *top, struct mbuf *control, int flags, struct thread *p)
static void sctp_sendall_completes(void *ptr, uint32_t val SCTP_UNUSED)
void sctp_send_abort_tcb(struct sctp_tcb *stcb, struct mbuf *operr, int so_locked)
void sctp_send_asconf_ack(struct sctp_tcb *stcb)
void sctp_send_shutdown(struct sctp_tcb *stcb, struct sctp_nets *net)
static void sctp_add_an_in_stream(struct sctp_tmit_chunk *chk, uint32_t seq, uint16_t adding)
void sctp_send_shutdown_complete2(struct sockaddr *src, struct sockaddr *dst, struct sctphdr *sh, uint8_t mflowtype, uint32_t mflowid, uint16_t fibnum, uint32_t vrf_id, uint16_t port)
static bool sctp_are_there_new_addresses(struct sctp_association *asoc, struct mbuf *in_initpkt, int offset, int limit, struct sockaddr *src, struct mbuf **op_err)
static void sctp_send_resp_msg(struct sockaddr *src, struct sockaddr *dst, struct sctphdr *sh, uint32_t vtag, uint8_t type, struct mbuf *cause, uint8_t mflowtype, uint32_t mflowid, uint16_t fibnum, uint32_t vrf_id, uint16_t port)
void sctp_send_abort(struct mbuf *m, int iphlen, struct sockaddr *src, struct sockaddr *dst, struct sctphdr *sh, uint32_t vtag, struct mbuf *cause, uint8_t mflowtype, uint32_t mflowid, uint16_t fibnum, uint32_t vrf_id, uint16_t port)
static struct sctp_ifa * sctp_choose_boundall(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sctp_nets *net, sctp_route_t *ro, uint32_t vrf_id, uint8_t dest_is_priv, uint8_t dest_is_loop, int non_asoc_addr_ok, sa_family_t fam)
void sctp_send_ecn_echo(struct sctp_tcb *stcb, struct sctp_nets *net, uint32_t high_tsn)
static void sctp_add_an_out_stream(struct sctp_tmit_chunk *chk, uint32_t seq, uint16_t adding)
static struct mbuf * sctp_add_cookie(struct mbuf *init, int init_offset, struct mbuf *initack, int initack_offset, struct sctp_state_cookie *stc_in, uint8_t **signature)
int sctp_send_stream_reset_out_if_possible(struct sctp_tcb *stcb, int so_locked)
static void sctp_timer_validation(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sctp_association *asoc)
void sctp_chunk_output(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_where, int so_locked)
int sctp_v6src_match_nexthop(struct sockaddr_in6 *src6, sctp_route_t *ro)
#define SCTP_DATA_CHUNK_OVERHEAD(stcb)
int sctp_is_address_on_local_host(struct sockaddr *addr, uint32_t vrf_id)
struct sctp_tcb * sctp_aloc_assoc_connected(struct sctp_inpcb *inp, struct sockaddr *firstaddr, int *error, uint32_t override_tag, uint32_t initial_tsn, uint32_t vrf_id, uint16_t o_streams, uint16_t port, struct thread *p, int initialize_auth_params)
void sctp_free_ifa(struct sctp_ifa *sctp_ifap)
struct sctp_tcb * sctp_findassociation_ep_asocid(struct sctp_inpcb *inp, sctp_assoc_t asoc_id, int want_lock)
int sctp_add_remote_addr(struct sctp_tcb *stcb, struct sockaddr *newaddr, struct sctp_nets **netp, uint16_t port, int set_scope, int from)
struct sctp_ifn * sctp_find_ifn(void *ifn, uint32_t ifn_index)
int sctp_initiate_iterator(inp_func inpf, asoc_func af, inp_func inpe, uint32_t pcb_state, uint32_t pcb_features, uint32_t asoc_state, void *argp, uint32_t argi, end_func ef, struct sctp_inpcb *s_inp, uint8_t chunk_output_off)
struct sctp_nets * sctp_findnet(struct sctp_tcb *stcb, struct sockaddr *addr)
int sctp_free_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb, int from_inpcbfree, int from_location)
struct sctp_tcb * sctp_findassociation_ep_addr(struct sctp_inpcb **inp_p, struct sockaddr *remote, struct sctp_nets **netp, struct sockaddr *local, struct sctp_tcb *locked_tcb)
void sctp_add_local_addr_restricted(struct sctp_tcb *stcb, struct sctp_ifa *ifa)
int sctp_set_primary_addr(struct sctp_tcb *stcb, struct sockaddr *sa, struct sctp_nets *net)
struct sctp_vrf * sctp_find_vrf(uint32_t vrf_id)
#define SCTP_INITIALIZE_AUTH_PARAMS
#define SCTP_ADDR_DEFER_USE
#define SCTP_ADDR_IFA_UNUSEABLE
#define SCTP_BEING_DELETED
#define CHUNK_FLAGS_FRAGMENT_OK
#define SCTP_PCB_ANY_FLAGS
#define SCTP_MAX_STREAMS_AT_ONCE_RESET
#define SCTP_STREAM_OPENING
#define SCTP_ASOC_ANY_STATE
#define SCTP_STREAM_RESET_IN_FLIGHT
#define SCTP_STREAM_RESET_PENDING
#define SCTP_STREAM_CLOSED
#define CHUNK_FLAGS_PR_SCTP_TTL
#define CHUNK_FLAGS_PR_SCTP_BUF
#define SCTP_PCB_ANY_FEATURES
#define CHUNK_FLAGS_PR_SCTP_RTX
#define SCTP_TSN_LOG_SIZE
struct sctp_nets * sctp_find_alternate_net(struct sctp_tcb *stcb, struct sctp_nets *net, int mode)
#define PR_SCTP_ENABLED(x)
#define SCTP_STAT_INCR_BY(_x, _d)
#define SCTP_ADDR_CONFIRMED
#define PR_SCTP_INVALID_POLICY(x)
#define PR_SCTP_BUF_ENABLED(x)
#define INVALID_SINFO_FLAG(x)
#define SCTP_STAT_INCR_COUNTER64(_x)
#define SCTP_PR_SCTP_NONE
#define SCTP_SACK_IMMEDIATELY
#define PR_SCTP_POLICY(x)
#define SCTP_STAT_INCR(_x)
#define SCTP_STAT_DECR_GAUGE32(_x)
void sctp_pathmtu_adjustment(struct sctp_tcb *stcb, uint32_t mtu, bool resend)
#define sctp_free_a_chunk(_stcb, _chk, _so_locked)
#define sctp_free_a_strmoq(_stcb, _strmoq, _so_locked)
#define sctp_is_feature_on(inp, feature)
#define sctp_is_feature_off(inp, feature)
#define sctp_feature_off(inp, feature)
#define sctp_total_flight_increase(stcb, tp1)
#define sctp_is_mobility_feature_on(inp, feature)
#define sctp_free_remote_addr(__net)
#define sctp_ucount_decr(val)
#define sctp_alloc_a_chunk(_stcb, _chk)
#define sctp_alloc_a_strmoq(_stcb, _strmoq)
#define sctp_sbspace_sub(a, b)
#define sctp_flight_size_increase(tp1)
void sctp_misc_ints(uint8_t from, uint32_t a, uint32_t b, uint32_t c, uint32_t d)
struct mbuf * sctp_add_pad_tombuf(struct mbuf *m, int padlen)
uint32_t sctp_calculate_len(struct mbuf *m)
void sctp_timer_stop(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sctp_nets *net, uint32_t from)
void sctp_timer_start(int t_type, struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct sctp_nets *net)
void sctp_log_maxburst(struct sctp_tcb *stcb, struct sctp_nets *net, int error, int burst, uint8_t from)
struct sctp_paramhdr * sctp_get_next_param(struct mbuf *m, int offset, struct sctp_paramhdr *pull, int pull_limit)
void sctp_log_rwnd(uint8_t from, uint32_t peers_rwnd, uint32_t snd_size, uint32_t overhead)
struct mbuf * sctp_generate_cause(uint16_t code, char *info)
void sctp_ulp_notify(uint32_t notification, struct sctp_tcb *stcb, uint32_t error, void *data, int so_locked)
uint32_t sctp_select_a_tag(struct sctp_inpcb *inp, uint16_t lport, uint16_t rport, int check)
void sctp_abort_an_association(struct sctp_inpcb *inp, struct sctp_tcb *stcb, struct mbuf *op_err, bool timedout, int so_locked)
void sctp_log_block(uint8_t from, struct sctp_association *asoc, ssize_t sendlen)
uint32_t sctp_select_initial_TSN(struct sctp_pcb *inp)
void sctp_log_cwnd(struct sctp_tcb *stcb, struct sctp_nets *net, int augment, uint8_t from)
int sctp_cmpaddr(struct sockaddr *sa1, struct sockaddr *sa2)
caddr_t sctp_m_getptr(struct mbuf *m, int off, int len, uint8_t *in_ptr)
void sctp_log_nagle_event(struct sctp_tcb *stcb, int action)
struct mbuf * sctp_pad_lastmbuf(struct mbuf *m, int padval, struct mbuf *last_mbuf)
int sctp_release_pr_sctp_chunk(struct sctp_tcb *stcb, struct sctp_tmit_chunk *tp1, uint8_t sent, int so_locked)
void sctp_stop_timers_for_shutdown(struct sctp_tcb *stcb)
int sctp_is_there_an_abort_here(struct mbuf *m, int iphlen, uint32_t *vtag)
#define sctp_snd_sb_alloc(stcb, sz)
struct in_addr ip_src ip_dst
struct sctp_gap_ack_block gaps[SCTP_MAX_GAPS_INARRAY]
struct sctp_nets * last_sent_to
uint32_t cookie_preserve_req
uint16_t strm_realoutsize
struct timeval time_entered
uint32_t total_output_queue_size
unsigned int sent_queue_retran_cnt
unsigned int sent_queue_cnt_removeable
uint16_t stream_locked_on
uint8_t peer_supports_nat
sctp_auth_chklist_t * local_auth_chunks
uint32_t highest_tsn_inside_map
struct sctp_nets * alternate
uint32_t str_reset_seq_out
uint32_t my_last_reported_rwnd
struct sctpchunk_listhead send_queue
struct sctp_stream_out * strmout
struct sctpladdr sctp_restricted_addrs
unsigned int total_flight_count
struct sctpnetlisthead nets
uint8_t reconfig_supported
struct sctp_nets * last_control_chunk_from
uint8_t burst_limit_applied
uint32_t last_reset_action[SCTP_MAX_RESET_PARAMS]
struct sctp_laddr * last_used_address
uint32_t asconf_seq_out_acked
struct sctp_timer dack_timer
struct sctp_asconf_ackhead asconf_ack_sent
uint32_t mapping_array_base_tsn
uint8_t cmt_dac_pkts_rcvd
uint32_t str_reset_seq_in
unsigned int total_flight
unsigned int stream_queue_cnt
struct sctpchunk_listhead asconf_send_queue
struct sctp_nets * last_net_cmt_send_started
struct sctp_ss_functions ss_functions
uint8_t * nr_mapping_array
uint32_t my_rwnd_control_len
struct sctpchunk_listhead control_send_queue
unsigned int size_on_all_streams
uint32_t highest_tsn_inside_nr_map
unsigned int max_inbound_streams
sctp_hmaclist_t * local_hmacs
unsigned int data_pkts_seen
struct sctp_scoping scope
uint8_t pktdrop_supported
struct sctp_tmit_chunk * str_reset
uint32_t chunks_on_out_queue
unsigned int send_queue_cnt
int dup_tsns[SCTP_MAX_DUP_TSNS]
struct timeval time_last_sent
struct sctp_nonpad_sndrcvinfo def_send
uint16_t ecn_echo_cnt_onq
struct sctp_nets * primary_destination
struct sctp_cc_functions cc_functions
struct sctp_nets * last_data_chunk_from
struct sctpchunk_listhead sent_queue
unsigned int pre_open_streams
sctp_auth_chklist_t * peer_auth_chunks
unsigned int size_on_reasm_queue
uint8_t stream_reset_outstanding
uint32_t initial_init_rto_max
uint16_t strm_pending_add_size
uint32_t advanced_peer_ack_point
unsigned int sent_queue_cnt
void(* sctp_cwnd_update_packet_transmitted)(struct sctp_tcb *stcb, struct sctp_nets *net)
void(* sctp_cwnd_new_transmission_begins)(struct sctp_tcb *stcb, struct sctp_nets *net)
void(* sctp_cwnd_update_after_output)(struct sctp_tcb *stcb, struct sctp_nets *net, int burst_limit)
struct sctp_sndrcvinfo sndrcv
struct timeval timetodrop
uint8_t doing_fast_retransmit
uint8_t chunk_was_revoked
uint32_t num_pkts_since_cwr
uint32_t new_cumulative_tsn
struct sctp_heartbeat heartbeat
char address[SCTP_ADDRMAX]
struct sctp_heartbeat_info_param hb_info
union sctp_idata::@32 ppid_fsn
union sctp_sockstore address
struct sctp_ifalist ifalist
char ifn_name[SCTP_IFNAMSIZ]
uint16_t num_inbound_streams
uint16_t num_outbound_streams
struct socket * sctp_socket
union sctp_inpcb::@33 ip_inp
struct sctpasochead sctp_asoc_list
uint8_t reconfig_supported
struct sctp_nonpad_sndrcvinfo def_send
struct sctpladdr sctp_addr_list
struct sctp_laddr * next_addr_touse
uint8_t pktdrop_supported
uint8_t addr[SCTP_V6_ADDR_BYTES]
union sctp_sockstore _l_addr
struct sctp_ifa * _s_addr
uint32_t heartbeat_random1
uint8_t indx_of_eligible_next_to_use
uint32_t heartbeat_random2
struct timeval last_sent_time
struct sctp_timer rxt_timer
uint8_t src_addr_selected
sctp_assoc_t sinfo_assoc_id
struct sctp_nr_sack nr_sack
uint16_t num_nr_gap_ack_blks
uint16_t num_gap_ack_blks
uint32_t secret_key[SCTP_HOW_MANY_SECRETS][SCTP_NUMBER_OF_SECRETS]
char current_secret_number
sctp_auth_chklist_t * local_auth_chunks
uint16_t pre_open_stream_count
uint32_t adaptation_layer_indicator
sctp_hmaclist_t * local_hmacs
uint16_t max_open_streams_intome
uint8_t adaptation_layer_indicator_provided
uint16_t num_gap_ack_blks
uint32_t cumulative_tsn_ack
sctp_assoc_t sinfo_assoc_id
uint16_t sinfo_keynumber_valid
uint32_t sinfo_timetolive
void(* sctp_ss_packet_done)(struct sctp_tcb *stcb, struct sctp_nets *net, struct sctp_association *asoc)
void(* sctp_ss_clear)(struct sctp_tcb *stcb, struct sctp_association *asoc, bool clear_values)
bool(* sctp_ss_is_empty)(struct sctp_tcb *stcb, struct sctp_association *asoc)
void(* sctp_ss_remove_from_stream)(struct sctp_tcb *stcb, struct sctp_association *asoc, struct sctp_stream_out *strq, struct sctp_stream_queue_pending *sp)
bool(* sctp_ss_is_user_msgs_incomplete)(struct sctp_tcb *stcb, struct sctp_association *asoc)
void(* sctp_ss_scheduled)(struct sctp_tcb *stcb, struct sctp_nets *net, struct sctp_association *asoc, struct sctp_stream_out *strq, int moved_how_much)
void(* sctp_ss_add_to_stream)(struct sctp_tcb *stcb, struct sctp_association *asoc, struct sctp_stream_out *strq, struct sctp_stream_queue_pending *sp)
struct sctp_stream_out *(* sctp_ss_select_stream)(struct sctp_tcb *stcb, struct sctp_nets *net, struct sctp_association *asoc)
void(* sctp_ss_init)(struct sctp_tcb *stcb, struct sctp_association *asoc)
void(* sctp_ss_init_stream)(struct sctp_tcb *stcb, struct sctp_stream_out *strq, struct sctp_stream_out *with_strq)
uint8_t reserved[SCTP_RESERVE_SPACE]
uint32_t address[SCTP_ADDRESS_SIZE]
struct timeval time_entered
uint32_t tie_tag_peer_vtag
uint8_t identification[SCTP_IDENTIFICATION_SIZE]
uint32_t laddress[SCTP_ADDRESS_SIZE]
uint8_t last_msg_incomplete
uint32_t chunks_on_queues
uint32_t next_mid_ordered
uint32_t abandoned_unsent[1]
uint32_t next_mid_unordered
struct sctp_streamhead outqueue
uint32_t abandoned_sent[1]
uint16_t number_of_streams
uint16_t list_of_streams[]
uint32_t send_reset_at_tsn
uint16_t list_of_streams[]
uint32_t receivers_next_tsn
uint32_t senders_next_tsn
struct socket * sctp_socket
uint32_t freed_by_sorcv_sincelast
struct sctp_association asoc
struct sctp_block_entry * block_entry
struct sctp_inpcb * sctp_ep
union sctp_tmit_chunk::@34 rec
struct sctp_data_chunkrec data
struct timeval sent_rcv_time
struct sctp_association * asoc
struct sctp_ifnlist ifnlist
#define UDPSTAT_INC(name)