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 --- |