sctp_pcb.c (7d4b968b0fa6afc6bca132c27e2041c979ee6101) sctp_pcb.c (482444b4a58e000cd61107152cd4d5cc58b8a4e5)
1/*-
2 * Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * a) Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.

--- 34 unchanged lines hidden (view full) ---

43#include <netinet/sctp_header.h>
44#include <netinet/sctp_asconf.h>
45#include <netinet/sctp_output.h>
46#include <netinet/sctp_timer.h>
47#include <netinet/sctp_bsd_addr.h>
48#include <netinet/udp.h>
49
50
1/*-
2 * Copyright (c) 2001-2008, by Cisco Systems, Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * a) Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.

--- 34 unchanged lines hidden (view full) ---

43#include <netinet/sctp_header.h>
44#include <netinet/sctp_asconf.h>
45#include <netinet/sctp_output.h>
46#include <netinet/sctp_timer.h>
47#include <netinet/sctp_bsd_addr.h>
48#include <netinet/udp.h>
49
50
51struct sctp_base_info system_base_info;
51VNET_DEFINE(struct sctp_base_info, system_base_info);
52
53/* FIX: we don't handle multiple link local scopes */
54/* "scopeless" replacement IN6_ARE_ADDR_EQUAL */
55#ifdef INET6
56int
57SCTP6_ARE_ADDR_EQUAL(struct sockaddr_in6 *a, struct sockaddr_in6 *b)
58{
59 struct sockaddr_in6 tmp_a, tmp_b;
60
61 memcpy(&tmp_a, a, sizeof(struct sockaddr_in6));
52
53/* FIX: we don't handle multiple link local scopes */
54/* "scopeless" replacement IN6_ARE_ADDR_EQUAL */
55#ifdef INET6
56int
57SCTP6_ARE_ADDR_EQUAL(struct sockaddr_in6 *a, struct sockaddr_in6 *b)
58{
59 struct sockaddr_in6 tmp_a, tmp_b;
60
61 memcpy(&tmp_a, a, sizeof(struct sockaddr_in6));
62 if (sa6_embedscope(&tmp_a, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone)) != 0) {
62 if (sa6_embedscope(&tmp_a, MODULE_GLOBAL(ip6_use_defzone)) != 0) {
63 return 0;
64 }
65 memcpy(&tmp_b, b, sizeof(struct sockaddr_in6));
63 return 0;
64 }
65 memcpy(&tmp_b, b, sizeof(struct sockaddr_in6));
66 if (sa6_embedscope(&tmp_b, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone)) != 0) {
66 if (sa6_embedscope(&tmp_b, MODULE_GLOBAL(ip6_use_defzone)) != 0) {
67 return 0;
68 }
69 return (IN6_ARE_ADDR_EQUAL(&tmp_a.sin6_addr, &tmp_b.sin6_addr));
70}
71
72#endif
73
74void

--- 1928 unchanged lines hidden (view full) ---

2003 bzero(from6, sizeof(*from6));
2004 from6->sin6_family = AF_INET6;
2005 from6->sin6_len = sizeof(struct sockaddr_in6);
2006 from6->sin6_addr = ip6->ip6_src;
2007 from6->sin6_port = sh->src_port;
2008 /* Get the scopes in properly to the sin6 addr's */
2009 /* we probably don't need these operations */
2010 (void)sa6_recoverscope(from6);
67 return 0;
68 }
69 return (IN6_ARE_ADDR_EQUAL(&tmp_a.sin6_addr, &tmp_b.sin6_addr));
70}
71
72#endif
73
74void

--- 1928 unchanged lines hidden (view full) ---

2003 bzero(from6, sizeof(*from6));
2004 from6->sin6_family = AF_INET6;
2005 from6->sin6_len = sizeof(struct sockaddr_in6);
2006 from6->sin6_addr = ip6->ip6_src;
2007 from6->sin6_port = sh->src_port;
2008 /* Get the scopes in properly to the sin6 addr's */
2009 /* we probably don't need these operations */
2010 (void)sa6_recoverscope(from6);
2011 sa6_embedscope(from6, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone));
2011 sa6_embedscope(from6, MODULE_GLOBAL(ip6_use_defzone));
2012 break;
2013 }
2014#endif
2015 default:
2016 /* Currently not supported. */
2017 return (NULL);
2018 }
2019

--- 24 unchanged lines hidden (view full) ---

2044 bzero(to6, sizeof(*to6));
2045 to6->sin6_family = AF_INET6;
2046 to6->sin6_len = sizeof(struct sockaddr_in6);
2047 to6->sin6_addr = ip6->ip6_dst;
2048 to6->sin6_port = sh->dest_port;
2049 /* Get the scopes in properly to the sin6 addr's */
2050 /* we probably don't need these operations */
2051 (void)sa6_recoverscope(to6);
2012 break;
2013 }
2014#endif
2015 default:
2016 /* Currently not supported. */
2017 return (NULL);
2018 }
2019

--- 24 unchanged lines hidden (view full) ---

2044 bzero(to6, sizeof(*to6));
2045 to6->sin6_family = AF_INET6;
2046 to6->sin6_len = sizeof(struct sockaddr_in6);
2047 to6->sin6_addr = ip6->ip6_dst;
2048 to6->sin6_port = sh->dest_port;
2049 /* Get the scopes in properly to the sin6 addr's */
2050 /* we probably don't need these operations */
2051 (void)sa6_recoverscope(to6);
2052 sa6_embedscope(to6, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone));
2052 sa6_embedscope(to6, MODULE_GLOBAL(ip6_use_defzone));
2053 break;
2054 }
2055#endif
2056 default:
2057 /* TSNH */
2058 break;
2059 }
2060 if (sh->v_tag) {

--- 250 unchanged lines hidden (view full) ---

2311 }
2312 if (error != 0) {
2313 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
2314 SCTP_INP_INFO_WUNLOCK();
2315 return error;
2316 }
2317#endif /* IPSEC */
2318 SCTP_INCR_EP_COUNT();
2053 break;
2054 }
2055#endif
2056 default:
2057 /* TSNH */
2058 break;
2059 }
2060 if (sh->v_tag) {

--- 250 unchanged lines hidden (view full) ---

2311 }
2312 if (error != 0) {
2313 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_ep), inp);
2314 SCTP_INP_INFO_WUNLOCK();
2315 return error;
2316 }
2317#endif /* IPSEC */
2318 SCTP_INCR_EP_COUNT();
2319 inp->ip_inp.inp.inp_ip_ttl = MODULE_GLOBAL(MOD_INET, ip_defttl);
2319 inp->ip_inp.inp.inp_ip_ttl = MODULE_GLOBAL(ip_defttl);
2320 SCTP_INP_INFO_WUNLOCK();
2321
2322 so->so_pcb = (caddr_t)inp;
2323
2324 if ((SCTP_SO_TYPE(so) == SOCK_DGRAM) ||
2325 (SCTP_SO_TYPE(so) == SOCK_SEQPACKET)) {
2326 /* UDP style socket */
2327 inp->sctp_flags = (SCTP_PCB_FLAGS_UDPTYPE |

--- 355 unchanged lines hidden (view full) ---

2683 if (p && (error = prison_local_ip6(p->td_ucred, &sin6->sin6_addr,
2684 (SCTP_IPV6_V6ONLY(inp) != 0))) != 0) {
2685 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
2686 return (error);
2687 }
2688 if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
2689 bindall = 0;
2690 /* KAME hack: embed scopeid */
2320 SCTP_INP_INFO_WUNLOCK();
2321
2322 so->so_pcb = (caddr_t)inp;
2323
2324 if ((SCTP_SO_TYPE(so) == SOCK_DGRAM) ||
2325 (SCTP_SO_TYPE(so) == SOCK_SEQPACKET)) {
2326 /* UDP style socket */
2327 inp->sctp_flags = (SCTP_PCB_FLAGS_UDPTYPE |

--- 355 unchanged lines hidden (view full) ---

2683 if (p && (error = prison_local_ip6(p->td_ucred, &sin6->sin6_addr,
2684 (SCTP_IPV6_V6ONLY(inp) != 0))) != 0) {
2685 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
2686 return (error);
2687 }
2688 if (!IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
2689 bindall = 0;
2690 /* KAME hack: embed scopeid */
2691 if (sa6_embedscope(sin6, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone)) != 0) {
2691 if (sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone)) != 0) {
2692 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
2693 return (EINVAL);
2694 }
2695 }
2696 /* this must be cleared for ifa_ifwithaddr() */
2697 sin6->sin6_scope_id = 0;
2698 break;
2699 }

--- 109 unchanged lines hidden (view full) ---

2809 }
2810 }
2811 } else {
2812 uint16_t first, last, candidate;
2813 uint16_t count;
2814 int done;
2815
2816 if (ip_inp->inp_flags & INP_HIGHPORT) {
2692 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, EINVAL);
2693 return (EINVAL);
2694 }
2695 }
2696 /* this must be cleared for ifa_ifwithaddr() */
2697 sin6->sin6_scope_id = 0;
2698 break;
2699 }

--- 109 unchanged lines hidden (view full) ---

2809 }
2810 }
2811 } else {
2812 uint16_t first, last, candidate;
2813 uint16_t count;
2814 int done;
2815
2816 if (ip_inp->inp_flags & INP_HIGHPORT) {
2817 first = MODULE_GLOBAL(MOD_INET, ipport_hifirstauto);
2818 last = MODULE_GLOBAL(MOD_INET, ipport_hilastauto);
2817 first = MODULE_GLOBAL(ipport_hifirstauto);
2818 last = MODULE_GLOBAL(ipport_hilastauto);
2819 } else if (ip_inp->inp_flags & INP_LOWPORT) {
2820 if (p && (error =
2821 priv_check(p, PRIV_NETINET_RESERVEDPORT)
2822 )) {
2823 SCTP_INP_DECR_REF(inp);
2824 SCTP_INP_WUNLOCK(inp);
2825 SCTP_INP_INFO_WUNLOCK();
2826 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
2827 return (error);
2828 }
2819 } else if (ip_inp->inp_flags & INP_LOWPORT) {
2820 if (p && (error =
2821 priv_check(p, PRIV_NETINET_RESERVEDPORT)
2822 )) {
2823 SCTP_INP_DECR_REF(inp);
2824 SCTP_INP_WUNLOCK(inp);
2825 SCTP_INP_INFO_WUNLOCK();
2826 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, error);
2827 return (error);
2828 }
2829 first = MODULE_GLOBAL(MOD_INET, ipport_lowfirstauto);
2830 last = MODULE_GLOBAL(MOD_INET, ipport_lowlastauto);
2829 first = MODULE_GLOBAL(ipport_lowfirstauto);
2830 last = MODULE_GLOBAL(ipport_lowlastauto);
2831 } else {
2831 } else {
2832 first = MODULE_GLOBAL(MOD_INET, ipport_firstauto);
2833 last = MODULE_GLOBAL(MOD_INET, ipport_lastauto);
2832 first = MODULE_GLOBAL(ipport_firstauto);
2833 last = MODULE_GLOBAL(ipport_lastauto);
2834 }
2835 if (first > last) {
2836 uint16_t temp;
2837
2838 temp = first;
2839 first = last;
2840 last = temp;
2841 }

--- 310 unchanged lines hidden (view full) ---

3152 nasoc = LIST_NEXT(asoc, sctp_tcblist);
3153 if (asoc->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
3154 /* Skip guys being freed */
3155 /* asoc->sctp_socket = NULL; FIXME MT */
3156 cnt_in_sd++;
3157 SCTP_TCB_UNLOCK(asoc);
3158 continue;
3159 }
2834 }
2835 if (first > last) {
2836 uint16_t temp;
2837
2838 temp = first;
2839 first = last;
2840 last = temp;
2841 }

--- 310 unchanged lines hidden (view full) ---

3152 nasoc = LIST_NEXT(asoc, sctp_tcblist);
3153 if (asoc->asoc.state & SCTP_STATE_ABOUT_TO_BE_FREED) {
3154 /* Skip guys being freed */
3155 /* asoc->sctp_socket = NULL; FIXME MT */
3156 cnt_in_sd++;
3157 SCTP_TCB_UNLOCK(asoc);
3158 continue;
3159 }
3160 if ((SCTP_GET_STATE(&asoc->asoc) == SCTP_STATE_COOKIE_WAIT) ||
3161 (SCTP_GET_STATE(&asoc->asoc) == SCTP_STATE_COOKIE_ECHOED)) {
3160 if (((SCTP_GET_STATE(&asoc->asoc) == SCTP_STATE_COOKIE_WAIT) ||
3161 (SCTP_GET_STATE(&asoc->asoc) == SCTP_STATE_COOKIE_ECHOED)) &&
3162 (asoc->asoc.total_output_queue_size == 0)) {
3162 /*
3163 * If we have data in queue, we don't want
3164 * to just free since the app may have done,
3165 * send()/close or connect/send/close. And
3166 * it wants the data to get across first.
3167 */
3168 /* Just abandon things in the front states */
3169 if (sctp_free_assoc(inp, asoc, SCTP_PCBFREE_NOFORCE,

--- 580 unchanged lines hidden (view full) ---

3750
3751 /* Now generate a route for this guy */
3752#ifdef INET6
3753 /* KAME hack: embed scopeid */
3754 if (newaddr->sa_family == AF_INET6) {
3755 struct sockaddr_in6 *sin6;
3756
3757 sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
3163 /*
3164 * If we have data in queue, we don't want
3165 * to just free since the app may have done,
3166 * send()/close or connect/send/close. And
3167 * it wants the data to get across first.
3168 */
3169 /* Just abandon things in the front states */
3170 if (sctp_free_assoc(inp, asoc, SCTP_PCBFREE_NOFORCE,

--- 580 unchanged lines hidden (view full) ---

3751
3752 /* Now generate a route for this guy */
3753#ifdef INET6
3754 /* KAME hack: embed scopeid */
3755 if (newaddr->sa_family == AF_INET6) {
3756 struct sockaddr_in6 *sin6;
3757
3758 sin6 = (struct sockaddr_in6 *)&net->ro._l_addr;
3758 (void)sa6_embedscope(sin6, MODULE_GLOBAL(MOD_INET6, ip6_use_defzone));
3759 (void)sa6_embedscope(sin6, MODULE_GLOBAL(ip6_use_defzone));
3759 sin6->sin6_scope_id = 0;
3760 }
3761#endif
3762 SCTP_RTALLOC((sctp_route_t *) & net->ro, stcb->asoc.vrf_id);
3763
3764 if (SCTP_ROUTE_HAS_VALID_IFN(&net->ro)) {
3765 /* Get source address */
3766 net->ro._s_addr = sctp_source_address_selection(stcb->sctp_ep,

--- 153 unchanged lines hidden (view full) ---

3920
3921static uint32_t
3922sctp_aloc_a_assoc_id(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
3923{
3924 uint32_t id;
3925 struct sctpasochead *head;
3926 struct sctp_tcb *lstcb;
3927
3760 sin6->sin6_scope_id = 0;
3761 }
3762#endif
3763 SCTP_RTALLOC((sctp_route_t *) & net->ro, stcb->asoc.vrf_id);
3764
3765 if (SCTP_ROUTE_HAS_VALID_IFN(&net->ro)) {
3766 /* Get source address */
3767 net->ro._s_addr = sctp_source_address_selection(stcb->sctp_ep,

--- 153 unchanged lines hidden (view full) ---

3921
3922static uint32_t
3923sctp_aloc_a_assoc_id(struct sctp_inpcb *inp, struct sctp_tcb *stcb)
3924{
3925 uint32_t id;
3926 struct sctpasochead *head;
3927 struct sctp_tcb *lstcb;
3928
3929 SCTP_INP_WLOCK(inp);
3928try_again:
3929 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
3930 /* TSNH */
3930try_again:
3931 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE) {
3932 /* TSNH */
3933 SCTP_INP_WUNLOCK(inp);
3931 return (0);
3932 }
3934 return (0);
3935 }
3933 SCTP_INP_WLOCK(inp);
3936 /*
3937 * We don't allow assoc id to be 0, this is needed otherwise if the
3938 * id were to wrap we would have issues with some socket options.
3939 */
3940 if (inp->sctp_associd_counter == 0) {
3941 inp->sctp_associd_counter++;
3942 }
3934 id = inp->sctp_associd_counter;
3935 inp->sctp_associd_counter++;
3936 lstcb = sctp_findasoc_ep_asocid_locked(inp, (sctp_assoc_t) id, 0);
3937 if (lstcb) {
3938 goto try_again;
3939 }
3940 head = &inp->sctp_asocidhash[SCTP_PCBHASH_ASOC(id, inp->hashasocidmark)];
3941 LIST_INSERT_HEAD(head, stcb, sctp_tcbasocidhash);

--- 156 unchanged lines hidden (view full) ---

4098 return (NULL);
4099 }
4100 SCTP_TCB_LOCK(stcb);
4101
4102 /* now that my_vtag is set, add it to the hash */
4103 head = &SCTP_BASE_INFO(sctp_asochash)[SCTP_PCBHASH_ASOC(stcb->asoc.my_vtag, SCTP_BASE_INFO(hashasocmark))];
4104 /* put it in the bucket in the vtag hash of assoc's for the system */
4105 LIST_INSERT_HEAD(head, stcb, sctp_asocs);
3943 id = inp->sctp_associd_counter;
3944 inp->sctp_associd_counter++;
3945 lstcb = sctp_findasoc_ep_asocid_locked(inp, (sctp_assoc_t) id, 0);
3946 if (lstcb) {
3947 goto try_again;
3948 }
3949 head = &inp->sctp_asocidhash[SCTP_PCBHASH_ASOC(id, inp->hashasocidmark)];
3950 LIST_INSERT_HEAD(head, stcb, sctp_tcbasocidhash);

--- 156 unchanged lines hidden (view full) ---

4107 return (NULL);
4108 }
4109 SCTP_TCB_LOCK(stcb);
4110
4111 /* now that my_vtag is set, add it to the hash */
4112 head = &SCTP_BASE_INFO(sctp_asochash)[SCTP_PCBHASH_ASOC(stcb->asoc.my_vtag, SCTP_BASE_INFO(hashasocmark))];
4113 /* put it in the bucket in the vtag hash of assoc's for the system */
4114 LIST_INSERT_HEAD(head, stcb, sctp_asocs);
4106#ifdef MICHAELS_EXPERIMENT
4107 sctp_delete_from_timewait(stcb->asoc.my_vtag, inp->sctp_lport, stcb->rport);
4108#endif
4109 SCTP_INP_INFO_WUNLOCK();
4110
4111 if ((err = sctp_add_remote_addr(stcb, firstaddr, SCTP_DO_SETSCOPE, SCTP_ALLOC_ASOC))) {
4112 /* failure.. memory error? */
4113 if (asoc->strmout) {
4114 SCTP_FREE(asoc->strmout, SCTP_M_STRMO);
4115 asoc->strmout = NULL;
4116 }
4117 if (asoc->mapping_array) {
4118 SCTP_FREE(asoc->mapping_array, SCTP_M_MAP);
4119 asoc->mapping_array = NULL;
4120 }
4115 SCTP_INP_INFO_WUNLOCK();
4116
4117 if ((err = sctp_add_remote_addr(stcb, firstaddr, SCTP_DO_SETSCOPE, SCTP_ALLOC_ASOC))) {
4118 /* failure.. memory error? */
4119 if (asoc->strmout) {
4120 SCTP_FREE(asoc->strmout, SCTP_M_STRMO);
4121 asoc->strmout = NULL;
4122 }
4123 if (asoc->mapping_array) {
4124 SCTP_FREE(asoc->mapping_array, SCTP_M_MAP);
4125 asoc->mapping_array = NULL;
4126 }
4127 if (asoc->nr_mapping_array) {
4128 SCTP_FREE(asoc->nr_mapping_array, SCTP_M_MAP);
4129 asoc->nr_mapping_array = NULL;
4130 }
4121 SCTP_DECR_ASOC_COUNT();
4122 SCTP_TCB_LOCK_DESTROY(stcb);
4123 SCTP_TCB_SEND_LOCK_DESTROY(stcb);
4124 LIST_REMOVE(stcb, sctp_tcbasocidhash);
4125 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_asoc), stcb);
4126 SCTP_INP_WUNLOCK(inp);
4127 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, ENOBUFS);
4128 *error = ENOBUFS;

--- 175 unchanged lines hidden (view full) ---

4304void
4305sctp_add_vtag_to_timewait(uint32_t tag, uint32_t time, uint16_t lport, uint16_t rport)
4306{
4307 struct sctpvtaghead *chain;
4308 struct sctp_tagblock *twait_block;
4309 struct timeval now;
4310 int set, i;
4311
4131 SCTP_DECR_ASOC_COUNT();
4132 SCTP_TCB_LOCK_DESTROY(stcb);
4133 SCTP_TCB_SEND_LOCK_DESTROY(stcb);
4134 LIST_REMOVE(stcb, sctp_tcbasocidhash);
4135 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_asoc), stcb);
4136 SCTP_INP_WUNLOCK(inp);
4137 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_PCB, ENOBUFS);
4138 *error = ENOBUFS;

--- 175 unchanged lines hidden (view full) ---

4314void
4315sctp_add_vtag_to_timewait(uint32_t tag, uint32_t time, uint16_t lport, uint16_t rport)
4316{
4317 struct sctpvtaghead *chain;
4318 struct sctp_tagblock *twait_block;
4319 struct timeval now;
4320 int set, i;
4321
4322 if (time == 0) {
4323 /* Its disabled */
4324 return;
4325 }
4312 (void)SCTP_GETTIME_TIMEVAL(&now);
4313 chain = &SCTP_BASE_INFO(vtag_timewait)[(tag % SCTP_STACK_VTAG_HASH_SIZE)];
4314 set = 0;
4315 if (!SCTP_LIST_EMPTY(chain)) {
4316 /* Block(s) present, lets find space, and expire on the fly */
4317 LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) {
4318 for (i = 0; i < SCTP_NUMBER_IN_VTAG_BLOCK; i++) {
4319 if ((twait_block->vtag_block[i].v_tag == 0) &&

--- 216 unchanged lines hidden (view full) ---

4536 * assures that it will be
4537 * added right after this
4538 * msg.
4539 */
4540 uint32_t strseq;
4541
4542 stcb->asoc.control_pdapi = sq;
4543 strseq = (sq->sinfo_stream << 16) | sq->sinfo_ssn;
4326 (void)SCTP_GETTIME_TIMEVAL(&now);
4327 chain = &SCTP_BASE_INFO(vtag_timewait)[(tag % SCTP_STACK_VTAG_HASH_SIZE)];
4328 set = 0;
4329 if (!SCTP_LIST_EMPTY(chain)) {
4330 /* Block(s) present, lets find space, and expire on the fly */
4331 LIST_FOREACH(twait_block, chain, sctp_nxt_tagblock) {
4332 for (i = 0; i < SCTP_NUMBER_IN_VTAG_BLOCK; i++) {
4333 if ((twait_block->vtag_block[i].v_tag == 0) &&

--- 216 unchanged lines hidden (view full) ---

4550 * assures that it will be
4551 * added right after this
4552 * msg.
4553 */
4554 uint32_t strseq;
4555
4556 stcb->asoc.control_pdapi = sq;
4557 strseq = (sq->sinfo_stream << 16) | sq->sinfo_ssn;
4544 sctp_notify_partial_delivery_indication(stcb,
4545 SCTP_PARTIAL_DELIVERY_ABORTED, 1, strseq);
4558 sctp_ulp_notify(SCTP_NOTIFY_PARTIAL_DELVIERY_INDICATION,
4559 stcb,
4560 SCTP_PARTIAL_DELIVERY_ABORTED,
4561 (void *)&strseq,
4562 SCTP_SO_LOCKED);
4546 stcb->asoc.control_pdapi = NULL;
4547 }
4548 }
4549 /* Add an end to wake them */
4550 sq->end_added = 1;
4551 cnt++;
4552 }
4553 }

--- 101 unchanged lines hidden (view full) ---

4655 LIST_REMOVE(stcb, sctp_tcblist);
4656 if (from_inpcbfree == SCTP_NORMAL_PROC) {
4657 SCTP_INP_INCR_REF(inp);
4658 SCTP_INP_WUNLOCK(inp);
4659 SCTP_ITERATOR_UNLOCK();
4660 }
4661 /* pull from vtag hash */
4662 LIST_REMOVE(stcb, sctp_asocs);
4563 stcb->asoc.control_pdapi = NULL;
4564 }
4565 }
4566 /* Add an end to wake them */
4567 sq->end_added = 1;
4568 cnt++;
4569 }
4570 }

--- 101 unchanged lines hidden (view full) ---

4672 LIST_REMOVE(stcb, sctp_tcblist);
4673 if (from_inpcbfree == SCTP_NORMAL_PROC) {
4674 SCTP_INP_INCR_REF(inp);
4675 SCTP_INP_WUNLOCK(inp);
4676 SCTP_ITERATOR_UNLOCK();
4677 }
4678 /* pull from vtag hash */
4679 LIST_REMOVE(stcb, sctp_asocs);
4663 sctp_add_vtag_to_timewait(asoc->my_vtag, SCTP_TIME_WAIT, inp->sctp_lport, stcb->rport);
4680 sctp_add_vtag_to_timewait(asoc->my_vtag, SCTP_BASE_SYSCTL(sctp_vtag_time_wait),
4681 inp->sctp_lport, stcb->rport);
4664
4665 /*
4666 * Now restop the timers to be sure - this is paranoia at is finest!
4667 */
4668 (void)SCTP_OS_TIMER_STOP(&asoc->strreset_timer.timer);
4669 (void)SCTP_OS_TIMER_STOP(&asoc->hb_timer.timer);
4670 (void)SCTP_OS_TIMER_STOP(&asoc->dack_timer.timer);
4671 (void)SCTP_OS_TIMER_STOP(&asoc->strreset_timer.timer);

--- 203 unchanged lines hidden (view full) ---

4875 printf("Freed %d from reasm_queue\n", ccnt);
4876 ccnt = 0;
4877 }
4878*/
4879 if (asoc->mapping_array) {
4880 SCTP_FREE(asoc->mapping_array, SCTP_M_MAP);
4881 asoc->mapping_array = NULL;
4882 }
4682
4683 /*
4684 * Now restop the timers to be sure - this is paranoia at is finest!
4685 */
4686 (void)SCTP_OS_TIMER_STOP(&asoc->strreset_timer.timer);
4687 (void)SCTP_OS_TIMER_STOP(&asoc->hb_timer.timer);
4688 (void)SCTP_OS_TIMER_STOP(&asoc->dack_timer.timer);
4689 (void)SCTP_OS_TIMER_STOP(&asoc->strreset_timer.timer);

--- 203 unchanged lines hidden (view full) ---

4893 printf("Freed %d from reasm_queue\n", ccnt);
4894 ccnt = 0;
4895 }
4896*/
4897 if (asoc->mapping_array) {
4898 SCTP_FREE(asoc->mapping_array, SCTP_M_MAP);
4899 asoc->mapping_array = NULL;
4900 }
4901 if (asoc->nr_mapping_array) {
4902 SCTP_FREE(asoc->nr_mapping_array, SCTP_M_MAP);
4903 asoc->nr_mapping_array = NULL;
4904 }
4883 /* the stream outs */
4884 if (asoc->strmout) {
4885 SCTP_FREE(asoc->strmout, SCTP_M_STRMO);
4886 asoc->strmout = NULL;
4887 }
4888 asoc->strm_realoutsize = asoc->streamoutcnt = 0;
4889 if (asoc->strmin) {
4890 struct sctp_queued_to_read *ctl;

--- 1133 unchanged lines hidden (view full) ---

6024 (struct sctp_paramhdr *)&local_store, min(sizeof(local_store), plen));
6025 if (phdr == NULL) {
6026 return (-25);
6027 }
6028 stcb->asoc.peer_supports_asconf = 0;
6029 stcb->asoc.peer_supports_prsctp = 0;
6030 stcb->asoc.peer_supports_pktdrop = 0;
6031 stcb->asoc.peer_supports_strreset = 0;
4905 /* the stream outs */
4906 if (asoc->strmout) {
4907 SCTP_FREE(asoc->strmout, SCTP_M_STRMO);
4908 asoc->strmout = NULL;
4909 }
4910 asoc->strm_realoutsize = asoc->streamoutcnt = 0;
4911 if (asoc->strmin) {
4912 struct sctp_queued_to_read *ctl;

--- 1133 unchanged lines hidden (view full) ---

6046 (struct sctp_paramhdr *)&local_store, min(sizeof(local_store), plen));
6047 if (phdr == NULL) {
6048 return (-25);
6049 }
6050 stcb->asoc.peer_supports_asconf = 0;
6051 stcb->asoc.peer_supports_prsctp = 0;
6052 stcb->asoc.peer_supports_pktdrop = 0;
6053 stcb->asoc.peer_supports_strreset = 0;
6054 stcb->asoc.peer_supports_nr_sack = 0;
6032 stcb->asoc.peer_supports_auth = 0;
6033 pr_supported = (struct sctp_supported_chunk_types_param *)phdr;
6034 num_ent = plen - sizeof(struct sctp_paramhdr);
6035 for (i = 0; i < num_ent; i++) {
6036 switch (pr_supported->chunk_types[i]) {
6037 case SCTP_ASCONF:
6038 case SCTP_ASCONF_ACK:
6039 stcb->asoc.peer_supports_asconf = 1;
6040 break;
6041 case SCTP_FORWARD_CUM_TSN:
6042 stcb->asoc.peer_supports_prsctp = 1;
6043 break;
6044 case SCTP_PACKET_DROPPED:
6045 stcb->asoc.peer_supports_pktdrop = 1;
6046 break;
6055 stcb->asoc.peer_supports_auth = 0;
6056 pr_supported = (struct sctp_supported_chunk_types_param *)phdr;
6057 num_ent = plen - sizeof(struct sctp_paramhdr);
6058 for (i = 0; i < num_ent; i++) {
6059 switch (pr_supported->chunk_types[i]) {
6060 case SCTP_ASCONF:
6061 case SCTP_ASCONF_ACK:
6062 stcb->asoc.peer_supports_asconf = 1;
6063 break;
6064 case SCTP_FORWARD_CUM_TSN:
6065 stcb->asoc.peer_supports_prsctp = 1;
6066 break;
6067 case SCTP_PACKET_DROPPED:
6068 stcb->asoc.peer_supports_pktdrop = 1;
6069 break;
6070 case SCTP_NR_SELECTIVE_ACK:
6071 if (SCTP_BASE_SYSCTL(sctp_nr_sack_on_off))
6072 stcb->asoc.peer_supports_nr_sack = 1;
6073 else
6074 stcb->asoc.peer_supports_nr_sack = 0;
6075 break;
6047 case SCTP_STREAM_RESET:
6048 stcb->asoc.peer_supports_strreset = 1;
6049 break;
6050 case SCTP_AUTHENTICATION:
6051 stcb->asoc.peer_supports_auth = 1;
6052 break;
6053 default:
6054 /* one I have not learned yet */

--- 310 unchanged lines hidden (view full) ---

6365 /* Bad tag, sorry :< */
6366 SCTP_INP_INFO_WUNLOCK();
6367 return (0);
6368 }
6369 }
6370 }
6371 }
6372 SCTP_INP_INFO_RUNLOCK();
6076 case SCTP_STREAM_RESET:
6077 stcb->asoc.peer_supports_strreset = 1;
6078 break;
6079 case SCTP_AUTHENTICATION:
6080 stcb->asoc.peer_supports_auth = 1;
6081 break;
6082 default:
6083 /* one I have not learned yet */

--- 310 unchanged lines hidden (view full) ---

6394 /* Bad tag, sorry :< */
6395 SCTP_INP_INFO_WUNLOCK();
6396 return (0);
6397 }
6398 }
6399 }
6400 }
6401 SCTP_INP_INFO_RUNLOCK();
6373#ifdef MICHAELS_EXPERIMENT
6374 /*-
6375 * Not found, ok to use the tag, add it to the time wait hash
6376 * as well this will prevent two sucessive cookies from getting
6377 * the same tag or two inits sent quickly on multi-processors.
6378 * We only keep the tag for the life of a cookie and when we
6379 * add this tag to the assoc hash we need to purge it from
6380 * the t-wait hash.
6381 */
6382 SCTP_INP_INFO_WLOCK();
6383 if (save_in_twait)
6384 sctp_add_vtag_to_timewait(tag, TICKS_TO_SEC(inp->sctp_ep.def_cookie_life, lport, rport));
6385 SCTP_INP_INFO_WUNLOCK();
6386#endif
6387
6388 return (1);
6389}
6390
6391
6392static sctp_assoc_t reneged_asoc_ids[256];
6393static uint8_t reneged_at = 0;
6394
6395

--- 281 unchanged lines hidden ---
6402 return (1);
6403}
6404
6405
6406static sctp_assoc_t reneged_asoc_ids[256];
6407static uint8_t reneged_at = 0;
6408
6409

--- 281 unchanged lines hidden ---