sctputil.c (169655) | sctputil.c (170056) |
---|---|
1/*- 2 * Copyright (c) 2001-2007, 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. --- 17 unchanged lines hidden (view full) --- 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 * THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31/* $KAME: sctputil.c,v 1.37 2005/03/07 23:26:09 itojun Exp $ */ 32 33#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2001-2007, 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. --- 17 unchanged lines hidden (view full) --- 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 * THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31/* $KAME: sctputil.c,v 1.37 2005/03/07 23:26:09 itojun Exp $ */ 32 33#include <sys/cdefs.h> |
34__FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 169655 2007-05-17 12:16:24Z rrs $"); | 34__FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 170056 2007-05-28 11:17:24Z rrs $"); |
35 36#include <netinet/sctp_os.h> 37#include <netinet/sctp_pcb.h> 38#include <netinet/sctputil.h> 39#include <netinet/sctp_var.h> 40#include <netinet/sctp_sysctl.h> 41#ifdef INET6 42#include <netinet6/sctp6_var.h> --- 875 unchanged lines hidden (view full) --- 918 int i; 919 920 /* init all variables to a known value. */ 921 asoc->state = SCTP_STATE_INUSE; 922 asoc->max_burst = m->sctp_ep.max_burst; 923 asoc->heart_beat_delay = TICKS_TO_MSEC(m->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]); 924 asoc->cookie_life = m->sctp_ep.def_cookie_life; 925 asoc->sctp_cmt_on_off = (uint8_t) sctp_cmt_on_off; | 35 36#include <netinet/sctp_os.h> 37#include <netinet/sctp_pcb.h> 38#include <netinet/sctputil.h> 39#include <netinet/sctp_var.h> 40#include <netinet/sctp_sysctl.h> 41#ifdef INET6 42#include <netinet6/sctp6_var.h> --- 875 unchanged lines hidden (view full) --- 918 int i; 919 920 /* init all variables to a known value. */ 921 asoc->state = SCTP_STATE_INUSE; 922 asoc->max_burst = m->sctp_ep.max_burst; 923 asoc->heart_beat_delay = TICKS_TO_MSEC(m->sctp_ep.sctp_timeoutticks[SCTP_TIMER_HEARTBEAT]); 924 asoc->cookie_life = m->sctp_ep.def_cookie_life; 925 asoc->sctp_cmt_on_off = (uint8_t) sctp_cmt_on_off; |
926 asoc->sctp_frag_point = m->sctp_frag_point; |
|
926#ifdef INET 927 asoc->default_tos = m->ip_inp.inp.inp_ip_tos; 928#else 929 asoc->default_tos = 0; 930#endif 931 932#ifdef INET6 933 asoc->default_flowlabel = ((struct in6pcb *)m)->in6p_flowinfo; --- 514 unchanged lines hidden (view full) --- 1448 * Not active, so no action. 1449 */ 1450 goto get_out; 1451 } 1452 SCTP_OS_TIMER_DEACTIVATE(&tmr->timer); 1453 1454 /* call the handler for the appropriate timer type */ 1455 switch (tmr->type) { | 927#ifdef INET 928 asoc->default_tos = m->ip_inp.inp.inp_ip_tos; 929#else 930 asoc->default_tos = 0; 931#endif 932 933#ifdef INET6 934 asoc->default_flowlabel = ((struct in6pcb *)m)->in6p_flowinfo; --- 514 unchanged lines hidden (view full) --- 1449 * Not active, so no action. 1450 */ 1451 goto get_out; 1452 } 1453 SCTP_OS_TIMER_DEACTIVATE(&tmr->timer); 1454 1455 /* call the handler for the appropriate timer type */ 1456 switch (tmr->type) { |
1457 case SCTP_TIMER_TYPE_ZERO_COPY: 1458 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_ZERO_COPY_ACTIVE)) { 1459 SCTP_ZERO_COPY_EVENT(inp, inp->sctp_socket); 1460 } 1461 break; |
|
1456 case SCTP_TIMER_TYPE_ADDR_WQ: 1457 sctp_handle_addr_wq(); 1458 break; 1459 case SCTP_TIMER_TYPE_ITERATOR: 1460 SCTP_STAT_INCR(sctps_timoiterator); 1461 sctp_iterator_timer(it); 1462 break; 1463 case SCTP_TIMER_TYPE_SEND: --- 301 unchanged lines hidden (view full) --- 1765 1766 to_ticks = 0; 1767 1768 tmr = NULL; 1769 if (stcb) { 1770 SCTP_TCB_LOCK_ASSERT(stcb); 1771 } 1772 switch (t_type) { | 1462 case SCTP_TIMER_TYPE_ADDR_WQ: 1463 sctp_handle_addr_wq(); 1464 break; 1465 case SCTP_TIMER_TYPE_ITERATOR: 1466 SCTP_STAT_INCR(sctps_timoiterator); 1467 sctp_iterator_timer(it); 1468 break; 1469 case SCTP_TIMER_TYPE_SEND: --- 301 unchanged lines hidden (view full) --- 1771 1772 to_ticks = 0; 1773 1774 tmr = NULL; 1775 if (stcb) { 1776 SCTP_TCB_LOCK_ASSERT(stcb); 1777 } 1778 switch (t_type) { |
1779 case SCTP_TIMER_TYPE_ZERO_COPY: 1780 tmr = &inp->sctp_ep.zero_copy_timer; 1781 to_ticks = SCTP_ZERO_COPY_TICK_DELAY; 1782 break; |
|
1773 case SCTP_TIMER_TYPE_ADDR_WQ: 1774 /* Only 1 tick away :-) */ 1775 tmr = &sctppcbinfo.addr_wq_timer; 1776 to_ticks = SCTP_ADDRESS_TICK_DELAY; 1777 break; 1778 case SCTP_TIMER_TYPE_ITERATOR: 1779 { 1780 struct sctp_iterator *it; --- 331 unchanged lines hidden (view full) --- 2112 (inp == NULL)) 2113 return; 2114 2115 tmr = NULL; 2116 if (stcb) { 2117 SCTP_TCB_LOCK_ASSERT(stcb); 2118 } 2119 switch (t_type) { | 1783 case SCTP_TIMER_TYPE_ADDR_WQ: 1784 /* Only 1 tick away :-) */ 1785 tmr = &sctppcbinfo.addr_wq_timer; 1786 to_ticks = SCTP_ADDRESS_TICK_DELAY; 1787 break; 1788 case SCTP_TIMER_TYPE_ITERATOR: 1789 { 1790 struct sctp_iterator *it; --- 331 unchanged lines hidden (view full) --- 2122 (inp == NULL)) 2123 return; 2124 2125 tmr = NULL; 2126 if (stcb) { 2127 SCTP_TCB_LOCK_ASSERT(stcb); 2128 } 2129 switch (t_type) { |
2130 case SCTP_TIMER_TYPE_ZERO_COPY: 2131 tmr = &inp->sctp_ep.zero_copy_timer; 2132 break; 2133 |
|
2120 case SCTP_TIMER_TYPE_ADDR_WQ: 2121 tmr = &sctppcbinfo.addr_wq_timer; 2122 break; 2123 case SCTP_TIMER_TYPE_EARLYFR: 2124 if ((stcb == NULL) || (net == NULL)) { 2125 return; 2126 } 2127 tmr = &net->fr_timer; --- 3081 unchanged lines hidden (view full) --- 5209 alen = atomic_fetchadd_int(&control->length, -(cp_len)); 5210 if (alen < cp_len) { 5211 panic("Control length goes negative2?"); 5212 } 5213 } else { 5214 copied_so_far += cp_len; 5215 } 5216 } | 2134 case SCTP_TIMER_TYPE_ADDR_WQ: 2135 tmr = &sctppcbinfo.addr_wq_timer; 2136 break; 2137 case SCTP_TIMER_TYPE_EARLYFR: 2138 if ((stcb == NULL) || (net == NULL)) { 2139 return; 2140 } 2141 tmr = &net->fr_timer; --- 3081 unchanged lines hidden (view full) --- 5223 alen = atomic_fetchadd_int(&control->length, -(cp_len)); 5224 if (alen < cp_len) { 5225 panic("Control length goes negative2?"); 5226 } 5227 } else { 5228 copied_so_far += cp_len; 5229 } 5230 } |
5217 if ((out_flags & MSG_EOR) || 5218 (uio->uio_resid == 0) 5219 ) { | 5231 if ((out_flags & MSG_EOR) || (uio->uio_resid == 0)) { |
5220 break; 5221 } 5222 if (((stcb) && (in_flags & MSG_PEEK) == 0) && 5223 (control->do_not_ref_stcb == 0) && 5224 (freed_so_far >= rwnd_req)) { 5225 sctp_user_rcvd(stcb, &freed_so_far, hold_rlock, rwnd_req); 5226 } 5227#ifdef SCTP_RECV_DETAIL_RWND_LOGGING --- 5 unchanged lines hidden (view full) --- 5233#endif 5234 5235 } /* end while(m) */ 5236 /* 5237 * At this point we have looked at it all and we either have 5238 * a MSG_EOR/or read all the user wants... <OR> 5239 * control->length == 0. 5240 */ | 5232 break; 5233 } 5234 if (((stcb) && (in_flags & MSG_PEEK) == 0) && 5235 (control->do_not_ref_stcb == 0) && 5236 (freed_so_far >= rwnd_req)) { 5237 sctp_user_rcvd(stcb, &freed_so_far, hold_rlock, rwnd_req); 5238 } 5239#ifdef SCTP_RECV_DETAIL_RWND_LOGGING --- 5 unchanged lines hidden (view full) --- 5245#endif 5246 5247 } /* end while(m) */ 5248 /* 5249 * At this point we have looked at it all and we either have 5250 * a MSG_EOR/or read all the user wants... <OR> 5251 * control->length == 0. 5252 */ |
5241 if ((out_flags & MSG_EOR) && 5242 ((in_flags & MSG_PEEK) == 0)) { | 5253 if ((out_flags & MSG_EOR) && ((in_flags & MSG_PEEK) == 0)) { |
5243 /* we are done with this control */ 5244 if (control->length == 0) { 5245 if (control->data) { 5246#ifdef INVARIANTS 5247 panic("control->data not null at read eor?"); 5248#else 5249 SCTP_PRINTF("Strange, data left in the control buffer .. invarients would panic?\n"); 5250 sctp_m_freem(control->data); --- 336 unchanged lines hidden (view full) --- 5587 */ 5588 wi = SCTP_ZONE_GET(sctppcbinfo.ipi_zone_laddr, struct sctp_laddr); 5589 if (wi == NULL) { 5590 return (ENOMEM); 5591 } 5592 /* Now incr the count and int wi structure */ 5593 SCTP_INCR_LADDR_COUNT(); 5594 bzero(wi, sizeof(*wi)); | 5254 /* we are done with this control */ 5255 if (control->length == 0) { 5256 if (control->data) { 5257#ifdef INVARIANTS 5258 panic("control->data not null at read eor?"); 5259#else 5260 SCTP_PRINTF("Strange, data left in the control buffer .. invarients would panic?\n"); 5261 sctp_m_freem(control->data); --- 336 unchanged lines hidden (view full) --- 5598 */ 5599 wi = SCTP_ZONE_GET(sctppcbinfo.ipi_zone_laddr, struct sctp_laddr); 5600 if (wi == NULL) { 5601 return (ENOMEM); 5602 } 5603 /* Now incr the count and int wi structure */ 5604 SCTP_INCR_LADDR_COUNT(); 5605 bzero(wi, sizeof(*wi)); |
5606 (void)SCTP_GETTIME_TIMEVAL(&wi->start_time); |
|
5595 wi->ifa = ifa; 5596 wi->action = SCTP_SET_PRIM_ADDR; 5597 atomic_add_int(&ifa->refcount, 1); 5598 5599 /* Now add it to the work queue */ 5600 SCTP_IPI_ITERATOR_WQ_LOCK(); 5601 /* 5602 * Should this really be a tailq? As it is we will process the --- 131 unchanged lines hidden (view full) --- 5734 5735 5736 5737 5738 5739 5740 5741int | 5607 wi->ifa = ifa; 5608 wi->action = SCTP_SET_PRIM_ADDR; 5609 atomic_add_int(&ifa->refcount, 1); 5610 5611 /* Now add it to the work queue */ 5612 SCTP_IPI_ITERATOR_WQ_LOCK(); 5613 /* 5614 * Should this really be a tailq? As it is we will process the --- 131 unchanged lines hidden (view full) --- 5746 5747 5748 5749 5750 5751 5752 5753int |
5742sctp_connectx_helper_add(struct sctp_tcb *stcb, struct sockaddr *addr, int totaddr, int *error) | 5754sctp_connectx_helper_add(struct sctp_tcb *stcb, struct sockaddr *addr, 5755 int totaddr, int *error) |
5743{ 5744 int added = 0; 5745 int i; 5746 struct sctp_inpcb *inp; 5747 struct sockaddr *sa; 5748 size_t incr = 0; 5749 5750 sa = addr; --- 21 unchanged lines hidden (view full) --- 5772 } 5773 sa = (struct sockaddr *)((caddr_t)sa + incr); 5774 } 5775out_now: 5776 return (added); 5777} 5778 5779struct sctp_tcb * | 5756{ 5757 int added = 0; 5758 int i; 5759 struct sctp_inpcb *inp; 5760 struct sockaddr *sa; 5761 size_t incr = 0; 5762 5763 sa = addr; --- 21 unchanged lines hidden (view full) --- 5785 } 5786 sa = (struct sockaddr *)((caddr_t)sa + incr); 5787 } 5788out_now: 5789 return (added); 5790} 5791 5792struct sctp_tcb * |
5780sctp_connectx_helper_find(struct sctp_inpcb *inp, struct sockaddr *addr, int *totaddr, 5781 int *num_v4, int *num_v6, int *error, int max) | 5793sctp_connectx_helper_find(struct sctp_inpcb *inp, struct sockaddr *addr, 5794 int *totaddr, int *num_v4, int *num_v6, int *error, 5795 int limit, int *bad_addr) |
5782{ 5783 struct sockaddr *sa; 5784 struct sctp_tcb *stcb = NULL; 5785 size_t incr, at, i; 5786 5787 at = incr = 0; 5788 sa = addr; 5789 *error = *num_v6 = *num_v4 = 0; 5790 /* account and validate addresses */ 5791 for (i = 0; i < *totaddr; i++) { 5792 if (sa->sa_family == AF_INET) { 5793 (*num_v4) += 1; 5794 incr = sizeof(struct sockaddr_in); | 5796{ 5797 struct sockaddr *sa; 5798 struct sctp_tcb *stcb = NULL; 5799 size_t incr, at, i; 5800 5801 at = incr = 0; 5802 sa = addr; 5803 *error = *num_v6 = *num_v4 = 0; 5804 /* account and validate addresses */ 5805 for (i = 0; i < *totaddr; i++) { 5806 if (sa->sa_family == AF_INET) { 5807 (*num_v4) += 1; 5808 incr = sizeof(struct sockaddr_in); |
5809 if (sa->sa_len != incr) { 5810 *error = EINVAL; 5811 *bad_addr = 1; 5812 return (NULL); 5813 } |
|
5795 } else if (sa->sa_family == AF_INET6) { 5796 struct sockaddr_in6 *sin6; 5797 5798 sin6 = (struct sockaddr_in6 *)sa; 5799 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { 5800 /* Must be non-mapped for connectx */ 5801 *error = EINVAL; | 5814 } else if (sa->sa_family == AF_INET6) { 5815 struct sockaddr_in6 *sin6; 5816 5817 sin6 = (struct sockaddr_in6 *)sa; 5818 if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { 5819 /* Must be non-mapped for connectx */ 5820 *error = EINVAL; |
5821 *bad_addr = 1; |
|
5802 return (NULL); 5803 } 5804 (*num_v6) += 1; 5805 incr = sizeof(struct sockaddr_in6); | 5822 return (NULL); 5823 } 5824 (*num_v6) += 1; 5825 incr = sizeof(struct sockaddr_in6); |
5826 if (sa->sa_len != incr) { 5827 *error = EINVAL; 5828 *bad_addr = 1; 5829 return (NULL); 5830 } |
|
5806 } else { 5807 *totaddr = i; 5808 /* we are done */ 5809 break; 5810 } | 5831 } else { 5832 *totaddr = i; 5833 /* we are done */ 5834 break; 5835 } |
5836 SCTP_INP_INCR_REF(inp); |
|
5811 stcb = sctp_findassociation_ep_addr(&inp, sa, NULL, NULL, NULL); 5812 if (stcb != NULL) { 5813 /* Already have or am bring up an association */ 5814 return (stcb); | 5837 stcb = sctp_findassociation_ep_addr(&inp, sa, NULL, NULL, NULL); 5838 if (stcb != NULL) { 5839 /* Already have or am bring up an association */ 5840 return (stcb); |
5841 } else { 5842 SCTP_INP_DECR_REF(inp); |
|
5815 } | 5843 } |
5816 if ((at + incr) > max) { | 5844 if ((at + incr) > limit) { |
5817 *totaddr = i; 5818 break; 5819 } 5820 sa = (struct sockaddr *)((caddr_t)sa + incr); 5821 } 5822 return ((struct sctp_tcb *)NULL); 5823} | 5845 *totaddr = i; 5846 break; 5847 } 5848 sa = (struct sockaddr *)((caddr_t)sa + incr); 5849 } 5850 return ((struct sctp_tcb *)NULL); 5851} |