Deleted Added
full compact
sctp_output.c (166675) sctp_output.c (167598)
1/*-
2 * Copyright (c) 2001-2007, 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: sctp_output.c,v 1.46 2005/03/06 16:04:17 itojun Exp $ */
32
33#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2001-2007, 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: sctp_output.c,v 1.46 2005/03/06 16:04:17 itojun Exp $ */
32
33#include <sys/cdefs.h>
34__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 166675 2007-02-12 23:24:31Z rrs $");
34__FBSDID("$FreeBSD: head/sys/netinet/sctp_output.c 167598 2007-03-15 11:27:14Z rrs $");
35
36#include <netinet/sctp_os.h>
37#include <sys/proc.h>
38#include <netinet/sctp_var.h>
35
36#include <netinet/sctp_os.h>
37#include <sys/proc.h>
38#include <netinet/sctp_var.h>
39#include <netinet/sctp_sysctl.h>
39#include <netinet/sctp_header.h>
40#include <netinet/sctp_pcb.h>
41#include <netinet/sctputil.h>
42#include <netinet/sctp_output.h>
43#include <netinet/sctp_uio.h>
44#include <netinet/sctputil.h>
45#include <netinet/sctp_auth.h>
46#include <netinet/sctp_timer.h>
47#include <netinet/sctp_asconf.h>
48#include <netinet/sctp_indata.h>
49#include <netinet/sctp_bsd_addr.h>
50
40#include <netinet/sctp_header.h>
41#include <netinet/sctp_pcb.h>
42#include <netinet/sctputil.h>
43#include <netinet/sctp_output.h>
44#include <netinet/sctp_uio.h>
45#include <netinet/sctputil.h>
46#include <netinet/sctp_auth.h>
47#include <netinet/sctp_timer.h>
48#include <netinet/sctp_asconf.h>
49#include <netinet/sctp_indata.h>
50#include <netinet/sctp_bsd_addr.h>
51
51#ifdef SCTP_DEBUG
52extern uint32_t sctp_debug_on;
53
52
54#endif
55
53
56
57
58#define SCTP_MAX_GAPS_INARRAY 4
59struct sack_track {
60 uint8_t right_edge; /* mergable on the right edge */
61 uint8_t left_edge; /* mergable on the left edge */
62 uint8_t num_entries;
63 uint8_t spare;
64 struct sctp_gap_ack_block gaps[SCTP_MAX_GAPS_INARRAY];
65};

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

1855 {0, 0},
1856 {0, 0},
1857 {0, 0}
1858 }
1859 }
1860};
1861
1862
54#define SCTP_MAX_GAPS_INARRAY 4
55struct sack_track {
56 uint8_t right_edge; /* mergable on the right edge */
57 uint8_t left_edge; /* mergable on the left edge */
58 uint8_t num_entries;
59 uint8_t spare;
60 struct sctp_gap_ack_block gaps[SCTP_MAX_GAPS_INARRAY];
61};

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

1851 {0, 0},
1852 {0, 0},
1853 {0, 0}
1854 }
1855 }
1856};
1857
1858
1859int
1860sctp_is_address_in_scope(struct sctp_ifa *ifa,
1861 int ipv4_addr_legal,
1862 int ipv6_addr_legal,
1863 int loopback_scope,
1864 int ipv4_local_scope,
1865 int local_scope,
1866 int site_scope,
1867 int do_update)
1868{
1869 if ((loopback_scope == 0) &&
1870 (ifa->ifn_p) && SCTP_IFN_IS_IFT_LOOP(ifa->ifn_p)) {
1871 /*
1872 * skip loopback if not in scope *
1873 */
1874 return (0);
1875 }
1876 if ((ifa->address.sa.sa_family == AF_INET) && ipv4_addr_legal) {
1877 struct sockaddr_in *sin;
1863
1878
1879 sin = (struct sockaddr_in *)&ifa->address.sin;
1880 if (sin->sin_addr.s_addr == 0) {
1881 /* not in scope , unspecified */
1882 return (0);
1883 }
1884 if ((ipv4_local_scope == 0) &&
1885 (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
1886 /* private address not in scope */
1887 return (0);
1888 }
1889 } else if ((ifa->address.sa.sa_family == AF_INET6) && ipv6_addr_legal) {
1890 struct sockaddr_in6 *sin6;
1864
1891
1865extern int sctp_peer_chunk_oh;
1892 /*
1893 * Must update the flags, bummer, which means any IFA locks
1894 * must now be applied HERE <->
1895 */
1896 if (do_update) {
1897 sctp_gather_internal_ifa_flags(ifa);
1898 }
1899 if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
1900 return (0);
1901 }
1902 /* ok to use deprecated addresses? */
1903 sin6 = (struct sockaddr_in6 *)&ifa->address.sin6;
1904 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
1905 /* skip unspecifed addresses */
1906 return (0);
1907 }
1908 if ( /* (local_scope == 0) && */
1909 (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))) {
1910 return (0);
1911 }
1912 if ((site_scope == 0) &&
1913 (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) {
1914 return (0);
1915 }
1916 } else {
1917 return (0);
1918 }
1919 return (1);
1920}
1866
1921
1922static struct mbuf *
1923sctp_add_addr_to_mbuf(struct mbuf *m, struct sctp_ifa *ifa)
1924{
1925 struct sctp_paramhdr *parmh;
1926 struct mbuf *mret;
1927 int len;
1928
1929 if (ifa->address.sa.sa_family == AF_INET) {
1930 len = sizeof(struct sctp_ipv4addr_param);
1931 } else if (ifa->address.sa.sa_family == AF_INET6) {
1932 len = sizeof(struct sctp_ipv6addr_param);
1933 } else {
1934 /* unknown type */
1935 return (m);
1936 }
1937 if (M_TRAILINGSPACE(m) >= len) {
1938 /* easy side we just drop it on the end */
1939 parmh = (struct sctp_paramhdr *)(SCTP_BUF_AT(m, SCTP_BUF_LEN(m)));
1940 mret = m;
1941 } else {
1942 /* Need more space */
1943 mret = m;
1944 while (SCTP_BUF_NEXT(mret) != NULL) {
1945 mret = SCTP_BUF_NEXT(mret);
1946 }
1947 SCTP_BUF_NEXT(mret) = sctp_get_mbuf_for_msg(len, 0, M_DONTWAIT, 1, MT_DATA);
1948 if (SCTP_BUF_NEXT(mret) == NULL) {
1949 /* We are hosed, can't add more addresses */
1950 return (m);
1951 }
1952 mret = SCTP_BUF_NEXT(mret);
1953 parmh = mtod(mret, struct sctp_paramhdr *);
1954 }
1955 /* now add the parameter */
1956 if (ifa->address.sa.sa_family == AF_INET) {
1957 struct sctp_ipv4addr_param *ipv4p;
1958 struct sockaddr_in *sin;
1959
1960 sin = (struct sockaddr_in *)&ifa->address.sin;
1961 ipv4p = (struct sctp_ipv4addr_param *)parmh;
1962 parmh->param_type = htons(SCTP_IPV4_ADDRESS);
1963 parmh->param_length = htons(len);
1964 ipv4p->addr = sin->sin_addr.s_addr;
1965 SCTP_BUF_LEN(mret) += len;
1966 } else if (ifa->address.sa.sa_family == AF_INET6) {
1967 struct sctp_ipv6addr_param *ipv6p;
1968 struct sockaddr_in6 *sin6;
1969
1970 sin6 = (struct sockaddr_in6 *)&ifa->address.sin6;
1971 ipv6p = (struct sctp_ipv6addr_param *)parmh;
1972 parmh->param_type = htons(SCTP_IPV6_ADDRESS);
1973 parmh->param_length = htons(len);
1974 memcpy(ipv6p->addr, &sin6->sin6_addr,
1975 sizeof(ipv6p->addr));
1976 /* clear embedded scope in the address */
1977 in6_clearscope((struct in6_addr *)ipv6p->addr);
1978 SCTP_BUF_LEN(mret) += len;
1979 } else {
1980 return (m);
1981 }
1982 return (mret);
1983}
1984
1985
1986struct mbuf *
1987sctp_add_addresses_to_i_ia(struct sctp_inpcb *inp, struct sctp_scoping *scope,
1988 struct mbuf *m_at, int cnt_inits_to)
1989{
1990 struct sctp_vrf *vrf = NULL;
1991 int cnt, limit_out = 0, total_count;
1992 uint32_t vrf_id;
1993
1994 vrf_id = SCTP_DEFAULT_VRFID;
1995 SCTP_IPI_ADDR_LOCK();
1996 vrf = sctp_find_vrf(vrf_id);
1997 if (vrf == NULL) {
1998 SCTP_IPI_ADDR_UNLOCK();
1999 return (m_at);
2000 }
2001 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
2002 struct sctp_ifa *sctp_ifap;
2003 struct sctp_ifn *sctp_ifnp;
2004
2005 cnt = cnt_inits_to;
2006 if (vrf->total_ifa_count > SCTP_COUNT_LIMIT) {
2007 limit_out = 1;
2008 cnt = SCTP_ADDRESS_LIMIT;
2009 goto skip_count;
2010 }
2011 LIST_FOREACH(sctp_ifnp, &vrf->ifnlist, next_ifn) {
2012 if ((scope->loopback_scope == 0) &&
2013 SCTP_IFN_IS_IFT_LOOP(sctp_ifnp)) {
2014 /*
2015 * Skip loopback devices if loopback_scope
2016 * not set
2017 */
2018 continue;
2019 }
2020 LIST_FOREACH(sctp_ifap, &sctp_ifnp->ifalist, next_ifa) {
2021 if (sctp_is_address_in_scope(sctp_ifap,
2022 scope->ipv4_addr_legal,
2023 scope->ipv6_addr_legal,
2024 scope->loopback_scope,
2025 scope->ipv4_local_scope,
2026 scope->local_scope,
2027 scope->site_scope, 1) == 0) {
2028 continue;
2029 }
2030 cnt++;
2031 if (cnt > SCTP_ADDRESS_LIMIT) {
2032 break;
2033 }
2034 }
2035 if (cnt > SCTP_ADDRESS_LIMIT) {
2036 break;
2037 }
2038 }
2039skip_count:
2040 if (cnt > 1) {
2041 total_count = 0;
2042 LIST_FOREACH(sctp_ifnp, &vrf->ifnlist, next_ifn) {
2043 cnt = 0;
2044 if ((scope->loopback_scope == 0) &&
2045 SCTP_IFN_IS_IFT_LOOP(sctp_ifnp)) {
2046 /*
2047 * Skip loopback devices if
2048 * loopback_scope not set
2049 */
2050 continue;
2051 }
2052 LIST_FOREACH(sctp_ifap, &sctp_ifnp->ifalist, next_ifa) {
2053 if (sctp_is_address_in_scope(sctp_ifap,
2054 scope->ipv4_addr_legal,
2055 scope->ipv6_addr_legal,
2056 scope->loopback_scope,
2057 scope->ipv4_local_scope,
2058 scope->local_scope,
2059 scope->site_scope, 0) == 0) {
2060 continue;
2061 }
2062 m_at = sctp_add_addr_to_mbuf(m_at, sctp_ifap);
2063 if (limit_out) {
2064 cnt++;
2065 total_count++;
2066 if (cnt >= 2) {
2067 /*
2068 * two from each
2069 * address
2070 */
2071 break;
2072 }
2073 if (total_count > SCTP_ADDRESS_LIMIT) {
2074 /* No more addresses */
2075 break;
2076 }
2077 }
2078 }
2079 }
2080 }
2081 } else {
2082 struct sctp_laddr *laddr;
2083
2084 cnt = cnt_inits_to;
2085 /* First, how many ? */
2086 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
2087 if (laddr->ifa == NULL) {
2088 continue;
2089 }
2090 if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED)
2091 /*
2092 * Address being deleted by the system, dont
2093 * list.
2094 */
2095 continue;
2096 if (laddr->action == SCTP_DEL_IP_ADDRESS) {
2097 /*
2098 * Address being deleted on this ep don't
2099 * list.
2100 */
2101 continue;
2102 }
2103 if (sctp_is_address_in_scope(laddr->ifa,
2104 scope->ipv4_addr_legal,
2105 scope->ipv6_addr_legal,
2106 scope->loopback_scope,
2107 scope->ipv4_local_scope,
2108 scope->local_scope,
2109 scope->site_scope, 1) == 0) {
2110 continue;
2111 }
2112 cnt++;
2113 }
2114 if (cnt > SCTP_ADDRESS_LIMIT) {
2115 limit_out = 1;
2116 }
2117 /*
2118 * To get through a NAT we only list addresses if we have
2119 * more than one. That way if you just bind a single address
2120 * we let the source of the init dictate our address.
2121 */
2122 if (cnt > 1) {
2123 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
2124 cnt = 0;
2125 if (laddr->ifa == NULL) {
2126 continue;
2127 }
2128 if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED)
2129 continue;
2130
2131 if (sctp_is_address_in_scope(laddr->ifa,
2132 scope->ipv4_addr_legal,
2133 scope->ipv6_addr_legal,
2134 scope->loopback_scope,
2135 scope->ipv4_local_scope,
2136 scope->local_scope,
2137 scope->site_scope, 0) == 0) {
2138 continue;
2139 }
2140 m_at = sctp_add_addr_to_mbuf(m_at, laddr->ifa);
2141 cnt++;
2142 if (cnt >= SCTP_ADDRESS_LIMIT) {
2143 break;
2144 }
2145 }
2146 }
2147 }
2148 SCTP_IPI_ADDR_UNLOCK();
2149 return (m_at);
2150}
2151
2152static struct sctp_ifa *
2153sctp_is_ifa_addr_prefered(struct sctp_ifa *ifa,
2154 uint8_t dest_is_loop,
2155 uint8_t dest_is_priv,
2156 sa_family_t fam)
2157{
2158 uint8_t dest_is_global = 0;
2159
2160 /*
2161 * is_scope -> dest_is_priv is true if destination is a private
2162 * address
2163 */
2164 /* dest_is_loop is true if destination is a loopback addresses */
2165
2166 /*
2167 * Here we determine if its a prefered address. A prefered address
2168 * means it is the same scope or higher scope then the destination.
2169 * L = loopback, P = private, G = global
2170 * ----------------------------------------- src | dest | result
2171 * ---------------------------------------- L | L | yes
2172 * ----------------------------------------- P | L |
2173 * yes-v4 no-v6 ----------------------------------------- G |
2174 * L | yes-v4 no-v6 ----------------------------------------- L
2175 * | P | no ----------------------------------------- P |
2176 * P | yes ----------------------------------------- G |
2177 * P | no ----------------------------------------- L | G
2178 * | no ----------------------------------------- P | G |
2179 * no ----------------------------------------- G | G |
2180 * yes -----------------------------------------
2181 */
2182
2183 if (ifa->address.sa.sa_family != fam) {
2184 /* forget mis-matched family */
2185 return (NULL);
2186 }
2187 if ((dest_is_priv == 0) && (dest_is_loop == 0)) {
2188 dest_is_global = 1;
2189 }
2190 /* Ok the address may be ok */
2191 if (fam == AF_INET6) {
2192 /* ok to use deprecated addresses? */
2193 if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
2194 return (NULL);
2195 }
2196 if (ifa->src_is_priv) {
2197 if (dest_is_loop) {
2198 return (NULL);
2199 }
2200 }
2201 if (ifa->src_is_glob) {
2202
2203 if (dest_is_loop) {
2204 return (NULL);
2205 }
2206 }
2207 }
2208 /*
2209 * Now that we know what is what, implement or table this could in
2210 * theory be done slicker (it used to be), but this is
2211 * straightforward and easier to validate :-)
2212 */
2213 if ((ifa->src_is_loop) && (dest_is_priv)) {
2214 return (NULL);
2215 }
2216 if ((ifa->src_is_glob) && (dest_is_priv)) {
2217 return (NULL);
2218 }
2219 if ((ifa->src_is_loop) && (dest_is_global)) {
2220 return (NULL);
2221 }
2222 if ((ifa->src_is_priv) && (dest_is_global)) {
2223 return (NULL);
2224 }
2225 /* its a prefered address */
2226 return (ifa);
2227}
2228
2229static struct sctp_ifa *
2230sctp_is_ifa_addr_acceptable(struct sctp_ifa *ifa,
2231 uint8_t dest_is_loop,
2232 uint8_t dest_is_priv,
2233 sa_family_t fam)
2234{
2235 uint8_t dest_is_global = 0;
2236
2237
2238 /*
2239 * Here we determine if its a acceptable address. A acceptable
2240 * address means it is the same scope or higher scope but we can
2241 * allow for NAT which means its ok to have a global dest and a
2242 * private src.
2243 *
2244 * L = loopback, P = private, G = global
2245 * ----------------------------------------- src | dest | result
2246 * ----------------------------------------- L | L | yes
2247 * ----------------------------------------- P | L |
2248 * yes-v4 no-v6 ----------------------------------------- G |
2249 * L | yes ----------------------------------------- L |
2250 * P | no ----------------------------------------- P | P
2251 * | yes ----------------------------------------- G | P
2252 * | yes - May not work -----------------------------------------
2253 * L | G | no ----------------------------------------- P
2254 * | G | yes - May not work
2255 * ----------------------------------------- G | G | yes
2256 * -----------------------------------------
2257 */
2258
2259 if (ifa->address.sa.sa_family != fam) {
2260 /* forget non matching family */
2261 return (NULL);
2262 }
2263 /* Ok the address may be ok */
2264 if ((dest_is_loop == 0) && (dest_is_priv == 0)) {
2265 dest_is_global = 1;
2266 }
2267 if (fam == AF_INET6) {
2268 /* ok to use deprecated addresses? */
2269 if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
2270 return (NULL);
2271 }
2272 if (ifa->src_is_priv) {
2273 /* Special case, linklocal to loop */
2274 if (dest_is_loop)
2275 return (NULL);
2276 }
2277 }
2278 /*
2279 * Now that we know what is what, implement or table this could in
2280 * theory be done slicker (it used to be), but this is
2281 * straightforward and easier to validate :-)
2282 */
2283
2284 if ((ifa->src_is_loop == 0) && (dest_is_priv)) {
2285 return (NULL);
2286 }
2287 if ((ifa->src_is_loop == 0) && (dest_is_global)) {
2288 return (NULL);
2289 }
2290 /* its an acceptable address */
2291 return (ifa);
2292}
2293
2294int
2295sctp_is_addr_restricted(struct sctp_tcb *stcb, struct sctp_ifa *ifa)
2296{
2297 struct sctp_laddr *laddr;
2298
2299 if (stcb == NULL) {
2300 /* There are no restrictions, no TCB :-) */
2301 return (0);
2302 }
2303 LIST_FOREACH(laddr, &stcb->asoc.sctp_restricted_addrs, sctp_nxt_addr) {
2304 if (laddr->ifa == NULL) {
2305#ifdef SCTP_DEBUG
2306 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) {
2307 printf("Help I have fallen and I can't get up!\n");
2308 }
2309#endif
2310 continue;
2311 }
2312 if (laddr->ifa == ifa) {
2313 /* Yes it is on the list */
2314 return (1);
2315 }
2316 }
2317 return (0);
2318}
2319
2320
2321int
2322sctp_is_addr_in_ep(struct sctp_inpcb *inp, struct sctp_ifa *ifa)
2323{
2324 struct sctp_laddr *laddr;
2325
2326 if (ifa == NULL)
2327 return (0);
2328 LIST_FOREACH(laddr, &inp->sctp_addr_list, sctp_nxt_addr) {
2329 if (laddr->ifa == NULL) {
2330#ifdef SCTP_DEBUG
2331 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) {
2332 printf("Help I have fallen and I can't get up!\n");
2333 }
2334#endif
2335 continue;
2336 }
2337 if ((laddr->ifa == ifa) && laddr->action == 0)
2338 /* same pointer */
2339 return (1);
2340 }
2341 return (0);
2342}
2343
2344
2345
2346static struct sctp_ifa *
2347sctp_choose_boundspecific_inp(struct sctp_inpcb *inp,
2348 struct route *ro,
2349 uint32_t vrf_id,
2350 int non_asoc_addr_ok,
2351 uint8_t dest_is_priv,
2352 uint8_t dest_is_loop,
2353 sa_family_t fam)
2354{
2355 struct sctp_laddr *laddr, *starting_point;
2356 void *ifn;
2357 int resettotop = 0;
2358 struct sctp_ifn *sctp_ifn;
2359 struct sctp_ifa *sctp_ifa, *pass;
2360 struct sctp_vrf *vrf;
2361 uint32_t ifn_index;
2362
2363 vrf = sctp_find_vrf(vrf_id);
2364 if (vrf == NULL)
2365 return (NULL);
2366
2367 ifn = SCTP_GET_IFN_VOID_FROM_ROUTE(ro);
2368 ifn_index = SCTP_GET_IF_INDEX_FROM_ROUTE(ro);
2369 sctp_ifn = sctp_find_ifn(vrf, ifn, ifn_index);
2370 /*
2371 * first question, is the ifn we will emit on in our list, if so, we
2372 * want such an address. Note that we first looked for a prefered
2373 * address.
2374 */
2375 if (sctp_ifn) {
2376 /* is a prefered one on the interface we route out? */
2377 LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
2378 if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0))
2379 continue;
2380 pass = sctp_is_ifa_addr_prefered(sctp_ifa, dest_is_loop, dest_is_priv, fam);
2381 if (pass == NULL)
2382 continue;
2383 if (sctp_is_addr_in_ep(inp, pass)) {
2384 atomic_add_int(&pass->refcount, 1);
2385 return (pass);
2386 }
2387 }
2388 }
2389 /*
2390 * ok, now we now need to find one on the list of the addresses. We
2391 * can't get one on the emitting interface so lets find first a
2392 * prefered one. If not that a acceptable one otherwise... we return
2393 * NULL.
2394 */
2395 starting_point = inp->next_addr_touse;
2396once_again:
2397 if (inp->next_addr_touse == NULL) {
2398 inp->next_addr_touse = LIST_FIRST(&inp->sctp_addr_list);
2399 resettotop = 1;
2400 }
2401 for (laddr = inp->next_addr_touse; laddr; laddr = LIST_NEXT(laddr, sctp_nxt_addr)) {
2402 if (laddr->ifa == NULL) {
2403 /* address has been removed */
2404 continue;
2405 }
2406 pass = sctp_is_ifa_addr_prefered(laddr->ifa, dest_is_loop, dest_is_priv, fam);
2407 if (pass == NULL)
2408 continue;
2409 atomic_add_int(&pass->refcount, 1);
2410 return (pass);
2411 }
2412 if (resettotop == 0) {
2413 inp->next_addr_touse = NULL;
2414 goto once_again;
2415 }
2416 inp->next_addr_touse = starting_point;
2417 resettotop = 0;
2418once_again_too:
2419 if (inp->next_addr_touse == NULL) {
2420 inp->next_addr_touse = LIST_FIRST(&inp->sctp_addr_list);
2421 resettotop = 1;
2422 }
2423 /* ok, what about an acceptable address in the inp */
2424 for (laddr = inp->next_addr_touse; laddr; laddr = LIST_NEXT(laddr, sctp_nxt_addr)) {
2425 if (laddr->ifa == NULL) {
2426 /* address has been removed */
2427 continue;
2428 }
2429 pass = sctp_is_ifa_addr_acceptable(laddr->ifa, dest_is_loop, dest_is_priv, fam);
2430 if (pass == NULL)
2431 continue;
2432 atomic_add_int(&pass->refcount, 1);
2433 return (pass);
2434 }
2435 if (resettotop == 0) {
2436 inp->next_addr_touse = NULL;
2437 goto once_again_too;
2438 }
2439 /*
2440 * no address bound can be a source for the destination we are in
2441 * trouble
2442 */
2443 return (NULL);
2444}
2445
2446
2447
2448static struct sctp_ifa *
2449sctp_choose_boundspecific_stcb(struct sctp_inpcb *inp,
2450 struct sctp_tcb *stcb,
2451 struct sctp_nets *net,
2452 struct route *ro,
2453 uint32_t vrf_id,
2454 uint8_t dest_is_priv,
2455 uint8_t dest_is_loop,
2456 int non_asoc_addr_ok,
2457 sa_family_t fam)
2458{
2459 struct sctp_laddr *laddr, *starting_point;
2460 void *ifn;
2461 struct sctp_ifn *sctp_ifn;
2462 struct sctp_ifa *sctp_ifa, *pass;
2463 uint8_t start_at_beginning = 0;
2464 struct sctp_vrf *vrf;
2465 uint32_t ifn_index;
2466
2467 /*
2468 * first question, is the ifn we will emit on in our list, if so, we
2469 * want that one.
2470 */
2471 vrf = sctp_find_vrf(vrf_id);
2472 if (vrf == NULL)
2473 return (NULL);
2474
2475 ifn = SCTP_GET_IFN_VOID_FROM_ROUTE(ro);
2476 ifn_index = SCTP_GET_IF_INDEX_FROM_ROUTE(ro);
2477 sctp_ifn = sctp_find_ifn(vrf, ifn, ifn_index);
2478
2479 /*
2480 * first question, is the ifn we will emit on in our list, if so, we
2481 * want that one.. First we look for a prefered. Second we go for an
2482 * acceptable.
2483 */
2484 if (sctp_ifn) {
2485 /* first try for an prefered address on the ep */
2486 LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
2487 if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0))
2488 continue;
2489 if (sctp_is_addr_in_ep(inp, sctp_ifa)) {
2490 pass = sctp_is_ifa_addr_prefered(sctp_ifa, dest_is_loop, dest_is_priv, fam);
2491 if (pass == NULL)
2492 continue;
2493 if ((non_asoc_addr_ok == 0) &&
2494 (sctp_is_addr_restricted(stcb, pass))) {
2495 /* on the no-no list */
2496 continue;
2497 }
2498 atomic_add_int(&pass->refcount, 1);
2499 return (pass);
2500 }
2501 }
2502 /* next try for an acceptable address on the ep */
2503 LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
2504 if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0))
2505 continue;
2506 if (sctp_is_addr_in_ep(inp, sctp_ifa)) {
2507 pass = sctp_is_ifa_addr_acceptable(sctp_ifa, dest_is_loop, dest_is_priv, fam);
2508 if (pass == NULL)
2509 continue;
2510 if ((non_asoc_addr_ok == 0) &&
2511 (sctp_is_addr_restricted(stcb, pass))) {
2512 /* on the no-no list */
2513 continue;
2514 }
2515 atomic_add_int(&pass->refcount, 1);
2516 return (pass);
2517 }
2518 }
2519
2520 }
2521 /*
2522 * if we can't find one like that then we must look at all addresses
2523 * bound to pick one at first prefereable then secondly acceptable.
2524 */
2525 starting_point = stcb->asoc.last_used_address;
2526sctp_from_the_top:
2527 if (stcb->asoc.last_used_address == NULL) {
2528 start_at_beginning = 1;
2529 stcb->asoc.last_used_address = LIST_FIRST(&inp->sctp_addr_list);
2530 }
2531 /* search beginning with the last used address */
2532 for (laddr = stcb->asoc.last_used_address; laddr;
2533 laddr = LIST_NEXT(laddr, sctp_nxt_addr)) {
2534 if (laddr->ifa == NULL) {
2535 /* address has been removed */
2536 continue;
2537 }
2538 pass = sctp_is_ifa_addr_prefered(laddr->ifa, dest_is_loop, dest_is_priv, fam);
2539 if (pass == NULL)
2540 continue;
2541 if ((non_asoc_addr_ok == 0) &&
2542 (sctp_is_addr_restricted(stcb, pass))) {
2543 /* on the no-no list */
2544 continue;
2545 }
2546 stcb->asoc.last_used_address = laddr;
2547 atomic_add_int(&pass->refcount, 1);
2548 return (pass);
2549
2550 }
2551 if (start_at_beginning == 0) {
2552 stcb->asoc.last_used_address = NULL;
2553 goto sctp_from_the_top;
2554 }
2555 /* now try for any higher scope than the destination */
2556 stcb->asoc.last_used_address = starting_point;
2557 start_at_beginning = 0;
2558sctp_from_the_top2:
2559 if (stcb->asoc.last_used_address == NULL) {
2560 start_at_beginning = 1;
2561 stcb->asoc.last_used_address = LIST_FIRST(&inp->sctp_addr_list);
2562 }
2563 /* search beginning with the last used address */
2564 for (laddr = stcb->asoc.last_used_address; laddr;
2565 laddr = LIST_NEXT(laddr, sctp_nxt_addr)) {
2566 if (laddr->ifa == NULL) {
2567 /* address has been removed */
2568 continue;
2569 }
2570 pass = sctp_is_ifa_addr_acceptable(laddr->ifa, dest_is_loop, dest_is_priv, fam);
2571 if (pass == NULL)
2572 continue;
2573 if ((non_asoc_addr_ok == 0) &&
2574 (sctp_is_addr_restricted(stcb, pass))) {
2575 /* on the no-no list */
2576 continue;
2577 }
2578 stcb->asoc.last_used_address = laddr;
2579 atomic_add_int(&pass->refcount, 1);
2580 return (pass);
2581 }
2582 if (start_at_beginning == 0) {
2583 stcb->asoc.last_used_address = NULL;
2584 goto sctp_from_the_top2;
2585 }
2586 return (NULL);
2587}
2588
2589static struct sctp_ifa *
2590sctp_select_nth_prefered_addr_from_ifn_boundall(struct sctp_ifn *ifn,
2591 struct sctp_tcb *stcb,
2592 int non_asoc_addr_ok,
2593 uint8_t dest_is_loop,
2594 uint8_t dest_is_priv,
2595 int addr_wanted,
2596 sa_family_t fam)
2597{
2598 struct sctp_ifa *ifa, *pass;
2599 int num_eligible_addr = 0;
2600
2601 LIST_FOREACH(ifa, &ifn->ifalist, next_ifa) {
2602 if ((ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0))
2603 continue;
2604 pass = sctp_is_ifa_addr_prefered(ifa, dest_is_loop, dest_is_priv, fam);
2605 if (pass == NULL)
2606 continue;
2607 if (stcb) {
2608 if ((non_asoc_addr_ok == 0) && sctp_is_addr_restricted(stcb, pass)) {
2609 /*
2610 * It is restricted for some reason..
2611 * probably not yet added.
2612 */
2613 continue;
2614 }
2615 }
2616 if (num_eligible_addr >= addr_wanted) {
2617 return (pass);
2618 }
2619 num_eligible_addr++;
2620 }
2621 return (NULL);
2622}
2623
2624
1867static int
2625static int
2626sctp_count_num_prefered_boundall(struct sctp_ifn *ifn,
2627 struct sctp_tcb *stcb,
2628 int non_asoc_addr_ok,
2629 uint8_t dest_is_loop,
2630 uint8_t dest_is_priv,
2631 sa_family_t fam)
2632{
2633 struct sctp_ifa *ifa, *pass;
2634 int num_eligible_addr = 0;
2635
2636 LIST_FOREACH(ifa, &ifn->ifalist, next_ifa) {
2637 if ((ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0)) {
2638 continue;
2639 }
2640 pass = sctp_is_ifa_addr_prefered(ifa, dest_is_loop, dest_is_priv, fam);
2641 if (pass == NULL) {
2642 continue;
2643 }
2644 if (stcb) {
2645 if ((non_asoc_addr_ok == 0) && sctp_is_addr_restricted(stcb, pass)) {
2646 /*
2647 * It is restricted for some reason..
2648 * probably not yet added.
2649 */
2650 continue;
2651 }
2652 }
2653 num_eligible_addr++;
2654 }
2655 return (num_eligible_addr);
2656}
2657
2658static struct sctp_ifa *
2659sctp_choose_boundall(struct sctp_inpcb *inp,
2660 struct sctp_tcb *stcb,
2661 struct sctp_nets *net,
2662 struct route *ro,
2663 uint32_t vrf_id,
2664 uint8_t dest_is_priv,
2665 uint8_t dest_is_loop,
2666 int non_asoc_addr_ok,
2667 sa_family_t fam)
2668{
2669 int cur_addr_num = 0, num_prefered = 0;
2670 void *ifn;
2671 struct sctp_ifn *sctp_ifn, *looked_at = NULL, *emit_ifn;
2672 struct sctp_ifa *sctp_ifa, *pass;
2673 uint32_t ifn_index;
2674 struct sctp_vrf *vrf;
2675
2676 /*
2677 * For boundall we can use any address in the association. If
2678 * non_asoc_addr_ok is set we can use any address (at least in
2679 * theory). So we look for prefered addresses first. If we find one,
2680 * we use it. Otherwise we next try to get an address on the
2681 * interface, which we should be able to do (unless non_asoc_addr_ok
2682 * is false and we are routed out that way). In these cases where we
2683 * can't use the address of the interface we go through all the
2684 * ifn's looking for an address we can use and fill that in. Punting
2685 * means we send back address 0, which will probably cause problems
2686 * actually since then IP will fill in the address of the route ifn,
2687 * which means we probably already rejected it.. i.e. here comes an
2688 * abort :-<.
2689 */
2690 vrf = sctp_find_vrf(vrf_id);
2691 if (vrf == NULL)
2692 return (NULL);
2693
2694 ifn = SCTP_GET_IFN_VOID_FROM_ROUTE(ro);
2695 ifn_index = SCTP_GET_IF_INDEX_FROM_ROUTE(ro);
2696
2697 emit_ifn = looked_at = sctp_ifn = sctp_find_ifn(vrf, ifn, ifn_index);
2698 if (sctp_ifn == NULL) {
2699 /* ?? We don't have this guy ?? */
2700 goto bound_all_plan_b;
2701 }
2702 if (net) {
2703 cur_addr_num = net->indx_of_eligible_next_to_use;
2704 }
2705 num_prefered = sctp_count_num_prefered_boundall(sctp_ifn,
2706 stcb,
2707 non_asoc_addr_ok,
2708 dest_is_loop,
2709 dest_is_priv, fam);
2710#ifdef SCTP_DEBUG
2711 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) {
2712 printf("Found %d prefered source addresses\n", num_prefered);
2713 }
2714#endif
2715 if (num_prefered == 0) {
2716 /*
2717 * no eligible addresses, we must use some other interface
2718 * address if we can find one.
2719 */
2720 goto bound_all_plan_b;
2721 }
2722 /*
2723 * Ok we have num_eligible_addr set with how many we can use, this
2724 * may vary from call to call due to addresses being deprecated
2725 * etc..
2726 */
2727 if (cur_addr_num >= num_prefered) {
2728 cur_addr_num = 0;
2729 }
2730 /*
2731 * select the nth address from the list (where cur_addr_num is the
2732 * nth) and 0 is the first one, 1 is the second one etc...
2733 */
2734#ifdef SCTP_DEBUG
2735 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) {
2736 printf("cur_addr_num:%d\n", cur_addr_num);
2737 }
2738#endif
2739 sctp_ifa = sctp_select_nth_prefered_addr_from_ifn_boundall(sctp_ifn, stcb, non_asoc_addr_ok, dest_is_loop,
2740 dest_is_priv, cur_addr_num, fam);
2741
2742 /* if sctp_ifa is NULL something changed??, fall to plan b. */
2743 if (sctp_ifa) {
2744 atomic_add_int(&sctp_ifa->refcount, 1);
2745 if (net) {
2746 /* save off where the next one we will want */
2747 net->indx_of_eligible_next_to_use = cur_addr_num + 1;
2748 }
2749 return (sctp_ifa);
2750 }
2751 /*
2752 * plan_b: Look at all interfaces and find a prefered address. If no
2753 * prefered fall through to plan_c.
2754 */
2755bound_all_plan_b:
2756 LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
2757 if (dest_is_loop == 0 && SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) {
2758 /* wrong base scope */
2759 continue;
2760 }
2761 if ((sctp_ifn == looked_at) && looked_at)
2762 /* already looked at this guy */
2763 continue;
2764 num_prefered = sctp_count_num_prefered_boundall(sctp_ifn, stcb, non_asoc_addr_ok,
2765 dest_is_loop, dest_is_priv, fam);
2766#ifdef SCTP_DEBUG
2767 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) {
2768 printf("Found ifn:%p %d prefered source addresses\n", ifn, num_prefered);
2769 }
2770#endif
2771 if (num_prefered == 0) {
2772 /*
2773 * None on this interface.
2774 */
2775 continue;
2776 }
2777#ifdef SCTP_DEBUG
2778 if (sctp_debug_on & SCTP_DEBUG_OUTPUT2) {
2779 printf("num prefered:%d on interface:%p cur_addr_num:%d\n",
2780 num_prefered,
2781 sctp_ifn,
2782 cur_addr_num);
2783 }
2784#endif
2785
2786 /*
2787 * Ok we have num_eligible_addr set with how many we can
2788 * use, this may vary from call to call due to addresses
2789 * being deprecated etc..
2790 */
2791 if (cur_addr_num >= num_prefered) {
2792 cur_addr_num = 0;
2793 }
2794 pass = sctp_select_nth_prefered_addr_from_ifn_boundall(sctp_ifn, stcb, non_asoc_addr_ok, dest_is_loop,
2795 dest_is_priv, cur_addr_num, fam);
2796 if (pass == NULL)
2797 continue;
2798 if (net) {
2799 net->indx_of_eligible_next_to_use = cur_addr_num + 1;
2800#ifdef SCTP_DEBUG
2801 if (sctp_debug_on & SCTP_DEBUG_OUTPUT2) {
2802 printf("we selected %d\n", cur_addr_num);
2803 printf("Source:");
2804 sctp_print_address(&pass->address.sa);
2805 printf("Dest:");
2806 sctp_print_address(&net->ro._l_addr.sa);
2807 }
2808#endif
2809 }
2810 atomic_add_int(&pass->refcount, 1);
2811 return (pass);
2812
2813 }
2814
2815 /*
2816 * plan_c: See if we have an acceptable address on the emit
2817 * interface
2818 */
2819#ifdef SCTP_DEBUG
2820 if (sctp_debug_on & SCTP_DEBUG_OUTPUT2) {
2821 if (net) {
2822 printf("Plan C no prefered for Dest:");
2823 sctp_print_address(&net->ro._l_addr.sa);
2824 }
2825 }
2826#endif
2827
2828 LIST_FOREACH(sctp_ifa, &emit_ifn->ifalist, next_ifa) {
2829 if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0))
2830 continue;
2831 pass = sctp_is_ifa_addr_acceptable(sctp_ifa, dest_is_loop, dest_is_priv, fam);
2832 if (pass == NULL)
2833 continue;
2834 if (stcb) {
2835 if ((non_asoc_addr_ok == 0) && sctp_is_addr_restricted(stcb, pass)) {
2836 /*
2837 * It is restricted for some reason..
2838 * probably not yet added.
2839 */
2840 continue;
2841 }
2842 }
2843 atomic_add_int(&pass->refcount, 1);
2844 return (pass);
2845 }
2846
2847 /*
2848 * plan_d: We are in trouble. No prefered address on the emit
2849 * interface. And not even a perfered address on all interfaces. Go
2850 * out and see if we can find an acceptable address somewhere
2851 * amongst all interfaces.
2852 */
2853 LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
2854 if (dest_is_loop == 0 && SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) {
2855 /* wrong base scope */
2856 continue;
2857 }
2858 if ((sctp_ifn == looked_at) && looked_at)
2859 /* already looked at this guy */
2860 continue;
2861
2862 LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
2863 if ((sctp_ifa->localifa_flags & SCTP_ADDR_DEFER_USE) && (non_asoc_addr_ok == 0))
2864 continue;
2865 pass = sctp_is_ifa_addr_acceptable(sctp_ifa, dest_is_loop, dest_is_priv, fam);
2866 if (pass == NULL)
2867 continue;
2868 if (stcb) {
2869 if ((non_asoc_addr_ok == 0) && sctp_is_addr_restricted(stcb, pass)) {
2870 /*
2871 * It is restricted for some
2872 * reason.. probably not yet added.
2873 */
2874 continue;
2875 }
2876 }
2877 atomic_add_int(&pass->refcount, 1);
2878 return (pass);
2879 }
2880 }
2881 /*
2882 * Ok we can find NO address to source from that is not on our
2883 * negative list and non_asoc_address is NOT ok, or its on our
2884 * negative list. We cant source to it :-(
2885 */
2886 return (NULL);
2887}
2888
2889
2890
2891/* tcb may be NULL */
2892struct sctp_ifa *
2893sctp_source_address_selection(struct sctp_inpcb *inp,
2894 struct sctp_tcb *stcb,
2895 struct route *ro,
2896 struct sctp_nets *net,
2897 int non_asoc_addr_ok, uint32_t vrf_id)
2898{
2899
2900 struct sockaddr_in *to = (struct sockaddr_in *)&ro->ro_dst;
2901 struct sockaddr_in6 *to6 = (struct sockaddr_in6 *)&ro->ro_dst;
2902 struct sctp_ifa *answer;
2903 uint8_t dest_is_priv, dest_is_loop;
2904 int did_rtalloc = 0;
2905 sa_family_t fam;
2906
2907 /*
2908 * Rules: - Find the route if needed, cache if I can. - Look at
2909 * interface address in route, Is it in the bound list. If so we
2910 * have the best source. - If not we must rotate amongst the
2911 * addresses.
2912 *
2913 * Cavets and issues
2914 *
2915 * Do we need to pay attention to scope. We can have a private address
2916 * or a global address we are sourcing or sending to. So if we draw
2917 * it out zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
2918 * For V4 ------------------------------------------ source *
2919 * dest * result ----------------------------------------- <a>
2920 * Private * Global * NAT
2921 * ----------------------------------------- <b> Private *
2922 * Private * No problem -----------------------------------------
2923 * <c> Global * Private * Huh, How will this work?
2924 * ----------------------------------------- <d> Global *
2925 * Global * No Problem ------------------------------------------
2926 * zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz For V6
2927 * ------------------------------------------ source * dest *
2928 * result ----------------------------------------- <a> Linklocal *
2929 * Global * ----------------------------------------- <b>
2930 * Linklocal * Linklocal * No problem
2931 * ----------------------------------------- <c> Global *
2932 * Linklocal * Huh, How will this work?
2933 * ----------------------------------------- <d> Global *
2934 * Global * No Problem ------------------------------------------
2935 * zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
2936 *
2937 * And then we add to that what happens if there are multiple addresses
2938 * assigned to an interface. Remember the ifa on a ifn is a linked
2939 * list of addresses. So one interface can have more than one IP
2940 * address. What happens if we have both a private and a global
2941 * address? Do we then use context of destination to sort out which
2942 * one is best? And what about NAT's sending P->G may get you a NAT
2943 * translation, or should you select the G thats on the interface in
2944 * preference.
2945 *
2946 * Decisions:
2947 *
2948 * - count the number of addresses on the interface. - if its one, no
2949 * problem except case <c>. For <a> we will assume a NAT out there.
2950 * - if there are more than one, then we need to worry about scope P
2951 * or G. We should prefer G -> G and P -> P if possible. Then as a
2952 * secondary fall back to mixed types G->P being a last ditch one. -
2953 * The above all works for bound all, but bound specific we need to
2954 * use the same concept but instead only consider the bound
2955 * addresses. If the bound set is NOT assigned to the interface then
2956 * we must use rotation amongst the bound addresses..
2957 *
2958 */
2959 if (ro->ro_rt == NULL) {
2960 /*
2961 * Need a route to cache.
2962 *
2963 */
2964 rtalloc_ign(ro, 0UL);
2965 did_rtalloc = 1;
2966 }
2967 if (ro->ro_rt == NULL) {
2968 return (NULL);
2969 }
2970 fam = to->sin_family;
2971 dest_is_priv = dest_is_loop = 0;
2972 /* Setup our scopes for the destination */
2973 if (fam == AF_INET) {
2974 /* Scope based on outbound address */
2975 if ((IN4_ISPRIVATE_ADDRESS(&to->sin_addr))) {
2976 dest_is_priv = 1;
2977 } else if (IN4_ISLOOPBACK_ADDRESS(&to->sin_addr)) {
2978 dest_is_loop = 1;
2979 if (net != NULL) {
2980 /* mark it as local */
2981 net->addr_is_local = 1;
2982 }
2983 }
2984 } else if (fam == AF_INET6) {
2985 /* Scope based on outbound address */
2986 if (IN6_IS_ADDR_LOOPBACK(&to6->sin6_addr)) {
2987 /*
2988 * If the route goes to the loopback address OR the
2989 * address is a loopback address, we are loopback
2990 * scope. But we don't use dest_is_priv (link local
2991 * addresses).
2992 */
2993 dest_is_loop = 1;
2994 if (net != NULL) {
2995 /* mark it as local */
2996 net->addr_is_local = 1;
2997 }
2998 } else if (IN6_IS_ADDR_LINKLOCAL(&to6->sin6_addr)) {
2999 dest_is_priv = 1;
3000 }
3001 }
3002 if (inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
3003 /*
3004 * When bound to all if the address list is set it is a
3005 * negative list. Addresses being added by asconf.
3006 */
3007 answer = sctp_choose_boundall(inp, stcb, net, ro, vrf_id,
3008 dest_is_priv,
3009 dest_is_loop,
3010 non_asoc_addr_ok,
3011 fam);
3012 return (answer);
3013 }
3014 /*
3015 * Three possiblities here:
3016 *
3017 * a) stcb is NULL, which means we operate only from the list of
3018 * addresses (ifa's) bound to the endpoint and we care not about the
3019 * list. b) stcb is NOT-NULL, which means we have an assoc structure
3020 * and auto-asconf is on. This means that the list of addresses is a
3021 * NOT list. We use the list from the inp, but any listed address in
3022 * our list is NOT yet added. However if the non_asoc_addr_ok is set
3023 * we CAN use an address NOT available (i.e. being added). Its a
3024 * negative list. c) stcb is NOT-NULL, which means we have an assoc
3025 * structure and auto-asconf is off. This means that the list of
3026 * addresses is the ONLY addresses I can use.. its positive.
3027 *
3028 * Note we collapse b & c into the same function just like in the v6
3029 * address selection.
3030 */
3031 if (stcb) {
3032 answer = sctp_choose_boundspecific_stcb(inp, stcb, net, ro, vrf_id,
3033 dest_is_priv, dest_is_loop, non_asoc_addr_ok, fam);
3034
3035 } else {
3036 answer = sctp_choose_boundspecific_inp(inp, ro, vrf_id, non_asoc_addr_ok, dest_is_priv, dest_is_loop, fam);
3037
3038 }
3039 return (answer);
3040}
3041
3042static int
1868sctp_find_cmsg(int c_type, void *data, struct mbuf *control, int cpsize)
1869{
1870 struct cmsghdr cmh;
1871 int tlen, at;
1872
1873 tlen = SCTP_BUF_LEN(control);
1874 at = 0;
1875 /*

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

1909 }
1910 }
1911 }
1912 /* not found */
1913 return (0);
1914}
1915
1916
3043sctp_find_cmsg(int c_type, void *data, struct mbuf *control, int cpsize)
3044{
3045 struct cmsghdr cmh;
3046 int tlen, at;
3047
3048 tlen = SCTP_BUF_LEN(control);
3049 at = 0;
3050 /*

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

3084 }
3085 }
3086 }
3087 /* not found */
3088 return (0);
3089}
3090
3091
1917extern int sctp_mbuf_threshold_count;
1918
1919
1920__inline struct mbuf *
3092struct mbuf *
1921sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header,
1922 int how, int allonebuf, int type)
1923{
1924 struct mbuf *m = NULL;
1925 int aloc_size;
1926 int index = 0;
1927 int mbuf_threshold;
1928

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

2116 stcb->asoc.hb_ect_randombit++;
2117 return (SCTP_ECT1_BIT);
2118 } else {
2119 stcb->asoc.hb_ect_randombit++;
2120 return (SCTP_ECT0_BIT);
2121 }
2122}
2123
3093sctp_get_mbuf_for_msg(unsigned int space_needed, int want_header,
3094 int how, int allonebuf, int type)
3095{
3096 struct mbuf *m = NULL;
3097 int aloc_size;
3098 int index = 0;
3099 int mbuf_threshold;
3100

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

3288 stcb->asoc.hb_ect_randombit++;
3289 return (SCTP_ECT1_BIT);
3290 } else {
3291 stcb->asoc.hb_ect_randombit++;
3292 return (SCTP_ECT0_BIT);
3293 }
3294}
3295
2124extern int sctp_no_csum_on_loopback;
2125
2126static int
2127sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
2128 struct sctp_tcb *stcb, /* may be NULL */
2129 struct sctp_nets *net,
2130 struct sockaddr *to,
2131 struct mbuf *m,
2132 uint32_t auth_offset,
2133 struct sctp_auth_chunk *auth,

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

2151 struct mbuf *o_pak;
2152
2153 struct sctphdr *sctphdr;
2154 int packet_length;
2155 int o_flgs;
2156 uint32_t csum;
2157 int ret;
2158 unsigned int have_mtu;
3296static int
3297sctp_lowlevel_chunk_output(struct sctp_inpcb *inp,
3298 struct sctp_tcb *stcb, /* may be NULL */
3299 struct sctp_nets *net,
3300 struct sockaddr *to,
3301 struct mbuf *m,
3302 uint32_t auth_offset,
3303 struct sctp_auth_chunk *auth,

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

3321 struct mbuf *o_pak;
3322
3323 struct sctphdr *sctphdr;
3324 int packet_length;
3325 int o_flgs;
3326 uint32_t csum;
3327 int ret;
3328 unsigned int have_mtu;
3329 uint32_t vrf_id;
2159 struct route *ro;
2160
3330 struct route *ro;
3331
3332
2161 if ((net) && (net->dest_state & SCTP_ADDR_OUT_OF_SCOPE)) {
2162 sctp_m_freem(m);
2163 return (EFAULT);
2164 }
3333 if ((net) && (net->dest_state & SCTP_ADDR_OUT_OF_SCOPE)) {
3334 sctp_m_freem(m);
3335 return (EFAULT);
3336 }
3337 if (stcb == NULL) {
3338 vrf_id = SCTP_DEFAULT_VRFID;
3339 } else {
3340 vrf_id = stcb->asoc.vrf_id;
3341 }
3342
2165 /* fill in the HMAC digest for any AUTH chunk in the packet */
2166 if ((auth != NULL) && (stcb != NULL)) {
2167 sctp_fill_hmac_digest_m(m, auth_offset, auth, stcb);
2168 }
2169 /* Calculate the csum and fill in the length of the packet */
2170 sctphdr = mtod(m, struct sctphdr *);
2171 have_mtu = 0;
2172 if (sctp_no_csum_on_loopback &&

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

2181 packet_length = sctp_calculate_len(m);
2182 } else {
2183 sctphdr->checksum = 0;
2184 csum = sctp_calculate_sum(m, &packet_length, 0);
2185 sctphdr->checksum = csum;
2186 }
2187
2188 if (to->sa_family == AF_INET) {
3343 /* fill in the HMAC digest for any AUTH chunk in the packet */
3344 if ((auth != NULL) && (stcb != NULL)) {
3345 sctp_fill_hmac_digest_m(m, auth_offset, auth, stcb);
3346 }
3347 /* Calculate the csum and fill in the length of the packet */
3348 sctphdr = mtod(m, struct sctphdr *);
3349 have_mtu = 0;
3350 if (sctp_no_csum_on_loopback &&

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

3359 packet_length = sctp_calculate_len(m);
3360 } else {
3361 sctphdr->checksum = 0;
3362 csum = sctp_calculate_sum(m, &packet_length, 0);
3363 sctphdr->checksum = csum;
3364 }
3365
3366 if (to->sa_family == AF_INET) {
2189 struct ip *ip;
3367 struct ip *ip = NULL;
2190 struct route iproute;
2191 uint8_t tos_value;
2192
2193 o_pak = SCTP_GET_HEADER_FOR_OUTPUT(sizeof(struct ip));
2194 if (o_pak == NULL) {
2195 /* failed to prepend data, give up */
2196 sctp_m_freem(m);
2197 return (ENOMEM);

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

2245 }
2246 /* Now the address selection part */
2247 ip->ip_dst.s_addr = ((struct sockaddr_in *)to)->sin_addr.s_addr;
2248
2249 /* call the routine to select the src address */
2250 if (net) {
2251 if (net->src_addr_selected == 0) {
2252 /* Cache the source address */
3368 struct route iproute;
3369 uint8_t tos_value;
3370
3371 o_pak = SCTP_GET_HEADER_FOR_OUTPUT(sizeof(struct ip));
3372 if (o_pak == NULL) {
3373 /* failed to prepend data, give up */
3374 sctp_m_freem(m);
3375 return (ENOMEM);

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

3423 }
3424 /* Now the address selection part */
3425 ip->ip_dst.s_addr = ((struct sockaddr_in *)to)->sin_addr.s_addr;
3426
3427 /* call the routine to select the src address */
3428 if (net) {
3429 if (net->src_addr_selected == 0) {
3430 /* Cache the source address */
2253 ((struct sockaddr_in *)&net->ro._s_addr)->sin_addr = sctp_ipv4_source_address_selection(inp,
2254 stcb,
2255 ro, net, out_of_asoc_ok);
2256 if (ro->ro_rt)
2257 net->src_addr_selected = 1;
3431 net->ro._s_addr = sctp_source_address_selection(inp, stcb,
3432 ro, net, out_of_asoc_ok, vrf_id);
3433 if (net->ro._s_addr == NULL) {
3434 /* No route to host */
3435 goto no_route;
3436 }
3437 net->src_addr_selected = 1;
2258 }
3438 }
2259 ip->ip_src = ((struct sockaddr_in *)&net->ro._s_addr)->sin_addr;
3439 ip->ip_src = net->ro._s_addr->address.sin.sin_addr;
2260 } else {
3440 } else {
2261 ip->ip_src = sctp_ipv4_source_address_selection(inp,
2262 stcb, ro, net, out_of_asoc_ok);
3441 struct sctp_ifa *_lsrc;
3442
3443 _lsrc = sctp_source_address_selection(inp,
3444 stcb, ro, net, out_of_asoc_ok, vrf_id);
3445 if (_lsrc == NULL) {
3446 goto no_route;
3447 }
3448 ip->ip_src = _lsrc->address.sin.sin_addr;
3449 sctp_free_ifa(_lsrc);
2263 }
2264
2265 /*
2266 * If source address selection fails and we find no route
2267 * then the ip_output should fail as well with a
2268 * NO_ROUTE_TO_HOST type error. We probably should catch
2269 * that somewhere and abort the association right away
2270 * (assuming this is an INIT being sent).
2271 */
2272 if ((ro->ro_rt == NULL)) {
2273 /*
2274 * src addr selection failed to find a route (or
2275 * valid source addr), so we can't get there from
3450 }
3451
3452 /*
3453 * If source address selection fails and we find no route
3454 * then the ip_output should fail as well with a
3455 * NO_ROUTE_TO_HOST type error. We probably should catch
3456 * that somewhere and abort the association right away
3457 * (assuming this is an INIT being sent).
3458 */
3459 if ((ro->ro_rt == NULL)) {
3460 /*
3461 * src addr selection failed to find a route (or
3462 * valid source addr), so we can't get there from
2276 * here!
3463 * here (yet)!
2277 */
3464 */
3465 no_route:
2278#ifdef SCTP_DEBUG
2279 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) {
3466#ifdef SCTP_DEBUG
3467 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) {
2280 printf("low_level_output: dropped v4 packet- no valid source addr\n");
2281 printf("Destination was %x\n", (uint32_t) (ntohl(ip->ip_dst.s_addr)));
3468 printf("low_level_output: dropped packet - no valid source addr\n");
3469 if (net) {
3470 printf("Destination was ");
3471 sctp_print_address(&net->ro._l_addr.sa);
3472 }
2282 }
2283#endif /* SCTP_DEBUG */
2284 if (net) {
3473 }
3474#endif /* SCTP_DEBUG */
3475 if (net) {
2285 if ((net->dest_state & SCTP_ADDR_REACHABLE) && stcb)
2286 sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN,
2287 stcb,
2288 SCTP_FAILED_THRESHOLD,
2289 (void *)net);
2290 net->dest_state &= ~SCTP_ADDR_REACHABLE;
2291 net->dest_state |= SCTP_ADDR_NOT_REACHABLE;
3476 if (net->dest_state & SCTP_ADDR_CONFIRMED) {
3477 if ((net->dest_state & SCTP_ADDR_REACHABLE) && stcb) {
3478 printf("no route takes interface %p down\n", net);
3479 sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN,
3480 stcb,
3481 SCTP_FAILED_THRESHOLD,
3482 (void *)net);
3483 net->dest_state &= ~SCTP_ADDR_REACHABLE;
3484 net->dest_state |= SCTP_ADDR_NOT_REACHABLE;
3485 }
3486 }
2292 if (stcb) {
2293 if (net == stcb->asoc.primary_destination) {
2294 /* need a new primary */
2295 struct sctp_nets *alt;
2296
2297 alt = sctp_find_alternate_net(stcb, net, 0);
2298 if (alt != net) {
2299 if (sctp_set_primary_addr(stcb,
2300 (struct sockaddr *)NULL,
2301 alt) == 0) {
2302 net->dest_state |= SCTP_ADDR_WAS_PRIMARY;
3487 if (stcb) {
3488 if (net == stcb->asoc.primary_destination) {
3489 /* need a new primary */
3490 struct sctp_nets *alt;
3491
3492 alt = sctp_find_alternate_net(stcb, net, 0);
3493 if (alt != net) {
3494 if (sctp_set_primary_addr(stcb,
3495 (struct sockaddr *)NULL,
3496 alt) == 0) {
3497 net->dest_state |= SCTP_ADDR_WAS_PRIMARY;
3498 if (net->ro._s_addr) {
3499 sctp_free_ifa(net->ro._s_addr);
3500 net->ro._s_addr = NULL;
3501 }
2303 net->src_addr_selected = 0;
2304 }
2305 }
2306 }
2307 }
2308 }
2309 sctp_m_freem(o_pak);
2310 return (EHOSTUNREACH);

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

2344 SCTP_STAT_INCR(sctps_senderrors);
2345#ifdef SCTP_DEBUG
2346 if (sctp_debug_on & SCTP_DEBUG_OUTPUT3) {
2347 printf("Ip output returns %d\n", ret);
2348 }
2349#endif
2350 if (net == NULL) {
2351 /* free tempy routes */
3502 net->src_addr_selected = 0;
3503 }
3504 }
3505 }
3506 }
3507 }
3508 sctp_m_freem(o_pak);
3509 return (EHOSTUNREACH);

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

3543 SCTP_STAT_INCR(sctps_senderrors);
3544#ifdef SCTP_DEBUG
3545 if (sctp_debug_on & SCTP_DEBUG_OUTPUT3) {
3546 printf("Ip output returns %d\n", ret);
3547 }
3548#endif
3549 if (net == NULL) {
3550 /* free tempy routes */
2352 if (ro->ro_rt)
3551 if (ro->ro_rt) {
2353 RTFREE(ro->ro_rt);
3552 RTFREE(ro->ro_rt);
3553 ro->ro_rt = NULL;
3554 }
2354 } else {
2355 /* PMTU check versus smallest asoc MTU goes here */
2356 if (ro->ro_rt != NULL) {
2357 if (ro->ro_rt->rt_rmx.rmx_mtu &&
2358 (stcb->asoc.smallest_mtu > ro->ro_rt->rt_rmx.rmx_mtu)) {
2359 sctp_mtu_size_reset(inp, &stcb->asoc,
2360 ro->ro_rt->rt_rmx.rmx_mtu);
2361 }
2362 } else {
2363 /* route was freed */
3555 } else {
3556 /* PMTU check versus smallest asoc MTU goes here */
3557 if (ro->ro_rt != NULL) {
3558 if (ro->ro_rt->rt_rmx.rmx_mtu &&
3559 (stcb->asoc.smallest_mtu > ro->ro_rt->rt_rmx.rmx_mtu)) {
3560 sctp_mtu_size_reset(inp, &stcb->asoc,
3561 ro->ro_rt->rt_rmx.rmx_mtu);
3562 }
3563 } else {
3564 /* route was freed */
3565 if (net->ro._s_addr &&
3566 net->src_addr_selected) {
3567 sctp_free_ifa(net->ro._s_addr);
3568 net->ro._s_addr = NULL;
3569 }
2364 net->src_addr_selected = 0;
2365 }
2366 }
2367 return (ret);
2368 }
2369#ifdef INET6
2370 else if (to->sa_family == AF_INET6) {
2371 uint32_t flowlabel;

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

2443 */
2444 bzero(&lsa6_tmp, sizeof(lsa6_tmp));
2445 lsa6_tmp.sin6_family = AF_INET6;
2446 lsa6_tmp.sin6_len = sizeof(lsa6_tmp);
2447 lsa6 = &lsa6_tmp;
2448 if (net) {
2449 if (net->src_addr_selected == 0) {
2450 /* Cache the source address */
3570 net->src_addr_selected = 0;
3571 }
3572 }
3573 return (ret);
3574 }
3575#ifdef INET6
3576 else if (to->sa_family == AF_INET6) {
3577 uint32_t flowlabel;

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

3649 */
3650 bzero(&lsa6_tmp, sizeof(lsa6_tmp));
3651 lsa6_tmp.sin6_family = AF_INET6;
3652 lsa6_tmp.sin6_len = sizeof(lsa6_tmp);
3653 lsa6 = &lsa6_tmp;
3654 if (net) {
3655 if (net->src_addr_selected == 0) {
3656 /* Cache the source address */
2451 ((struct sockaddr_in6 *)&net->ro._s_addr)->sin6_addr = sctp_ipv6_source_address_selection(inp,
2452 stcb, ro, net, out_of_asoc_ok);
2453
2454 if (ro->ro_rt)
2455 net->src_addr_selected = 1;
3657 net->ro._s_addr = sctp_source_address_selection(inp,
3658 stcb,
3659 ro,
3660 net,
3661 out_of_asoc_ok,
3662 vrf_id);
3663 if (net->ro._s_addr == NULL) {
3664#ifdef SCTP_DEBUG
3665 printf("V6:No route to host\n");
3666#endif
3667 goto no_route;
3668 }
3669 net->src_addr_selected = 1;
2456 }
3670 }
2457 lsa6->sin6_addr = ((struct sockaddr_in6 *)&net->ro._s_addr)->sin6_addr;
3671 lsa6->sin6_addr = net->ro._s_addr->address.sin6.sin6_addr;
2458 } else {
3672 } else {
2459 lsa6->sin6_addr = sctp_ipv6_source_address_selection(
2460 inp, stcb, ro, net, out_of_asoc_ok);
3673 struct sctp_ifa *_lsrc;
3674
3675 _lsrc = sctp_source_address_selection(inp, stcb, ro, net, out_of_asoc_ok, vrf_id);
3676 if (_lsrc == NULL) {
3677 goto no_route;
3678 }
3679 lsa6->sin6_addr = _lsrc->address.sin6.sin6_addr;
3680 sctp_free_ifa(_lsrc);
2461 }
2462 lsa6->sin6_port = inp->sctp_lport;
2463
2464 if ((ro->ro_rt == NULL)) {
2465 /*
2466 * src addr selection failed to find a route (or
2467 * valid source addr), so we can't get there from
2468 * here!
2469 */
3681 }
3682 lsa6->sin6_port = inp->sctp_lport;
3683
3684 if ((ro->ro_rt == NULL)) {
3685 /*
3686 * src addr selection failed to find a route (or
3687 * valid source addr), so we can't get there from
3688 * here!
3689 */
2470#ifdef SCTP_DEBUG
2471 if (sctp_debug_on & SCTP_DEBUG_OUTPUT1) {
2472 printf("low_level_output: dropped v6 pkt- no valid source addr\n");
2473 }
2474#endif
2475 sctp_m_freem(o_pak);
2476 if (net) {
2477 if ((net->dest_state & SCTP_ADDR_REACHABLE) && stcb)
2478 sctp_ulp_notify(SCTP_NOTIFY_INTERFACE_DOWN,
2479 stcb,
2480 SCTP_FAILED_THRESHOLD,
2481 (void *)net);
2482 net->dest_state &= ~SCTP_ADDR_REACHABLE;
2483 net->dest_state |= SCTP_ADDR_NOT_REACHABLE;
2484 if (stcb) {
2485 if (net == stcb->asoc.primary_destination) {
2486 /* need a new primary */
2487 struct sctp_nets *alt;
2488
2489 alt = sctp_find_alternate_net(stcb, net, 0);
2490 if (alt != net) {
2491 if (sctp_set_primary_addr(stcb,
2492 (struct sockaddr *)NULL,
2493 alt) == 0) {
2494 net->dest_state |= SCTP_ADDR_WAS_PRIMARY;
2495 net->src_addr_selected = 0;
2496 }
2497 }
2498 }
2499 }
2500 }
2501 return (EHOSTUNREACH);
3690 goto no_route;
2502 }
2503 /*
2504 * XXX: sa6 may not have a valid sin6_scope_id in the
2505 * non-SCOPEDROUTING case.
2506 */
2507 bzero(&lsa6_storage, sizeof(lsa6_storage));
2508 lsa6_storage.sin6_family = AF_INET6;
2509 lsa6_storage.sin6_len = sizeof(lsa6_storage);

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

2560 }
2561#ifdef SCTP_DEBUG
2562 if (sctp_debug_on & SCTP_DEBUG_OUTPUT3) {
2563 printf("return from send is %d\n", ret);
2564 }
2565#endif /* SCTP_DEBUG_OUTPUT */
2566 SCTP_STAT_INCR(sctps_sendpackets);
2567 SCTP_STAT_INCR_COUNTER64(sctps_outpackets);
3691 }
3692 /*
3693 * XXX: sa6 may not have a valid sin6_scope_id in the
3694 * non-SCOPEDROUTING case.
3695 */
3696 bzero(&lsa6_storage, sizeof(lsa6_storage));
3697 lsa6_storage.sin6_family = AF_INET6;
3698 lsa6_storage.sin6_len = sizeof(lsa6_storage);

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

3749 }
3750#ifdef SCTP_DEBUG
3751 if (sctp_debug_on & SCTP_DEBUG_OUTPUT3) {
3752 printf("return from send is %d\n", ret);
3753 }
3754#endif /* SCTP_DEBUG_OUTPUT */
3755 SCTP_STAT_INCR(sctps_sendpackets);
3756 SCTP_STAT_INCR_COUNTER64(sctps_outpackets);
2568 if (ret)
3757 if (ret) {
2569 SCTP_STAT_INCR(sctps_senderrors);
3758 SCTP_STAT_INCR(sctps_senderrors);
3759 }
2570 if (net == NULL) {
2571 /* Now if we had a temp route free it */
2572 if (ro->ro_rt) {
2573 RTFREE(ro->ro_rt);
2574 }
2575 } else {
2576 /* PMTU check versus smallest asoc MTU goes here */
2577 if (ro->ro_rt == NULL) {
2578 /* Route was freed */
3760 if (net == NULL) {
3761 /* Now if we had a temp route free it */
3762 if (ro->ro_rt) {
3763 RTFREE(ro->ro_rt);
3764 }
3765 } else {
3766 /* PMTU check versus smallest asoc MTU goes here */
3767 if (ro->ro_rt == NULL) {
3768 /* Route was freed */
3769
3770 if (net->ro._s_addr &&
3771 net->src_addr_selected) {
3772 sctp_free_ifa(net->ro._s_addr);
3773 net->ro._s_addr = NULL;
3774 }
2579 net->src_addr_selected = 0;
2580 }
2581 if (ro->ro_rt != NULL) {
2582 if (ro->ro_rt->rt_rmx.rmx_mtu &&
2583 (stcb->asoc.smallest_mtu > ro->ro_rt->rt_rmx.rmx_mtu)) {
2584 sctp_mtu_size_reset(inp,
2585 &stcb->asoc,
2586 ro->ro_rt->rt_rmx.rmx_mtu);

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

3259 struct sockaddr *to;
3260 struct sctp_state_cookie stc;
3261 struct sctp_nets *net = NULL;
3262 int cnt_inits_to = 0;
3263 uint16_t his_limit, i_want;
3264 int abort_flag, padval, sz_of;
3265 int num_ext;
3266 int p_len;
3775 net->src_addr_selected = 0;
3776 }
3777 if (ro->ro_rt != NULL) {
3778 if (ro->ro_rt->rt_rmx.rmx_mtu &&
3779 (stcb->asoc.smallest_mtu > ro->ro_rt->rt_rmx.rmx_mtu)) {
3780 sctp_mtu_size_reset(inp,
3781 &stcb->asoc,
3782 ro->ro_rt->rt_rmx.rmx_mtu);

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

4455 struct sockaddr *to;
4456 struct sctp_state_cookie stc;
4457 struct sctp_nets *net = NULL;
4458 int cnt_inits_to = 0;
4459 uint16_t his_limit, i_want;
4460 int abort_flag, padval, sz_of;
4461 int num_ext;
4462 int p_len;
4463 uint32_t vrf_id;
3267
4464
4465 vrf_id = SCTP_DEFAULT_VRFID;
3268 if (stcb) {
3269 asoc = &stcb->asoc;
3270 } else {
3271 asoc = NULL;
3272 }
3273 m_last = NULL;
3274 if ((asoc != NULL) &&
3275 (SCTP_GET_STATE(asoc) != SCTP_STATE_COOKIE_WAIT) &&

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

3353 /* now for scope setup */
3354 memset((caddr_t)&store, 0, sizeof(store));
3355 sin = (struct sockaddr_in *)&store;
3356 sin6 = (struct sockaddr_in6 *)&store;
3357 if (net == NULL) {
3358 to = (struct sockaddr *)&store;
3359 iph = mtod(init_pkt, struct ip *);
3360 if (iph->ip_v == IPVERSION) {
4466 if (stcb) {
4467 asoc = &stcb->asoc;
4468 } else {
4469 asoc = NULL;
4470 }
4471 m_last = NULL;
4472 if ((asoc != NULL) &&
4473 (SCTP_GET_STATE(asoc) != SCTP_STATE_COOKIE_WAIT) &&

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

4551 /* now for scope setup */
4552 memset((caddr_t)&store, 0, sizeof(store));
4553 sin = (struct sockaddr_in *)&store;
4554 sin6 = (struct sockaddr_in6 *)&store;
4555 if (net == NULL) {
4556 to = (struct sockaddr *)&store;
4557 iph = mtod(init_pkt, struct ip *);
4558 if (iph->ip_v == IPVERSION) {
3361 struct in_addr addr;
4559 struct sctp_ifa *addr;
3362 struct route iproute;
3363
3364 sin->sin_family = AF_INET;
3365 sin->sin_len = sizeof(struct sockaddr_in);
3366 sin->sin_port = sh->src_port;
3367 sin->sin_addr = iph->ip_src;
3368 /* lookup address */
3369 stc.address[0] = sin->sin_addr.s_addr;
3370 stc.address[1] = 0;
3371 stc.address[2] = 0;
3372 stc.address[3] = 0;
3373 stc.addr_type = SCTP_IPV4_ADDRESS;
3374 /* local from address */
3375 memset(&iproute, 0, sizeof(iproute));
3376 ro = &iproute;
3377 memcpy(&ro->ro_dst, sin, sizeof(*sin));
4560 struct route iproute;
4561
4562 sin->sin_family = AF_INET;
4563 sin->sin_len = sizeof(struct sockaddr_in);
4564 sin->sin_port = sh->src_port;
4565 sin->sin_addr = iph->ip_src;
4566 /* lookup address */
4567 stc.address[0] = sin->sin_addr.s_addr;
4568 stc.address[1] = 0;
4569 stc.address[2] = 0;
4570 stc.address[3] = 0;
4571 stc.addr_type = SCTP_IPV4_ADDRESS;
4572 /* local from address */
4573 memset(&iproute, 0, sizeof(iproute));
4574 ro = &iproute;
4575 memcpy(&ro->ro_dst, sin, sizeof(*sin));
3378 addr = sctp_ipv4_source_address_selection(inp, NULL,
3379 ro, NULL, 0);
4576 addr = sctp_source_address_selection(inp, NULL,
4577 ro, NULL, 0, vrf_id);
4578 if (addr == NULL)
4579 return;
4580
3380 if (ro->ro_rt) {
3381 RTFREE(ro->ro_rt);
4581 if (ro->ro_rt) {
4582 RTFREE(ro->ro_rt);
4583 ro->ro_rt = NULL;
3382 }
4584 }
3383 stc.laddress[0] = addr.s_addr;
4585 stc.laddress[0] = addr->address.sin.sin_addr.s_addr;
3384 stc.laddress[1] = 0;
3385 stc.laddress[2] = 0;
3386 stc.laddress[3] = 0;
3387 stc.laddr_type = SCTP_IPV4_ADDRESS;
3388 /* scope_id is only for v6 */
3389 stc.scope_id = 0;
3390#ifndef SCTP_DONT_DO_PRIVADDR_SCOPE
3391 if (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
3392 stc.ipv4_scope = 1;
3393 }
3394#else
3395 stc.ipv4_scope = 1;
3396#endif /* SCTP_DONT_DO_PRIVADDR_SCOPE */
3397 /* Must use the address in this case */
4586 stc.laddress[1] = 0;
4587 stc.laddress[2] = 0;
4588 stc.laddress[3] = 0;
4589 stc.laddr_type = SCTP_IPV4_ADDRESS;
4590 /* scope_id is only for v6 */
4591 stc.scope_id = 0;
4592#ifndef SCTP_DONT_DO_PRIVADDR_SCOPE
4593 if (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
4594 stc.ipv4_scope = 1;
4595 }
4596#else
4597 stc.ipv4_scope = 1;
4598#endif /* SCTP_DONT_DO_PRIVADDR_SCOPE */
4599 /* Must use the address in this case */
3398 if (sctp_is_address_on_local_host((struct sockaddr *)sin)) {
4600 if (sctp_is_address_on_local_host((struct sockaddr *)sin, vrf_id)) {
3399 stc.loopback_scope = 1;
3400 stc.ipv4_scope = 1;
3401 stc.site_scope = 1;
4601 stc.loopback_scope = 1;
4602 stc.ipv4_scope = 1;
4603 stc.site_scope = 1;
3402 stc.local_scope = 1;
4604 stc.local_scope = 0;
3403 }
3404 } else if (iph->ip_v == (IPV6_VERSION >> 4)) {
4605 }
4606 } else if (iph->ip_v == (IPV6_VERSION >> 4)) {
3405 struct in6_addr addr;
4607 struct sctp_ifa *addr;
3406
3407 struct route_in6 iproute6;
3408
3409 ip6 = mtod(init_pkt, struct ip6_hdr *);
3410 sin6->sin6_family = AF_INET6;
3411 sin6->sin6_len = sizeof(struct sockaddr_in6);
3412 sin6->sin6_port = sh->src_port;
3413 sin6->sin6_addr = ip6->ip6_src;
3414 /* lookup address */
3415 memcpy(&stc.address, &sin6->sin6_addr,
3416 sizeof(struct in6_addr));
3417 sin6->sin6_scope_id = 0;
3418 stc.addr_type = SCTP_IPV6_ADDRESS;
3419 stc.scope_id = 0;
4608
4609 struct route_in6 iproute6;
4610
4611 ip6 = mtod(init_pkt, struct ip6_hdr *);
4612 sin6->sin6_family = AF_INET6;
4613 sin6->sin6_len = sizeof(struct sockaddr_in6);
4614 sin6->sin6_port = sh->src_port;
4615 sin6->sin6_addr = ip6->ip6_src;
4616 /* lookup address */
4617 memcpy(&stc.address, &sin6->sin6_addr,
4618 sizeof(struct in6_addr));
4619 sin6->sin6_scope_id = 0;
4620 stc.addr_type = SCTP_IPV6_ADDRESS;
4621 stc.scope_id = 0;
3420 if (sctp_is_address_on_local_host((struct sockaddr *)sin6)) {
4622 if (sctp_is_address_on_local_host((struct sockaddr *)sin6, vrf_id)) {
3421 stc.loopback_scope = 1;
4623 stc.loopback_scope = 1;
3422 stc.local_scope = 1;
4624 stc.local_scope = 0;
3423 stc.site_scope = 1;
3424 stc.ipv4_scope = 1;
3425 } else if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
3426 /*
3427 * If the new destination is a LINK_LOCAL we
3428 * must have common both site and local
3429 * scope. Don't set local scope though since
3430 * we must depend on the source to be added

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

3454 * we must have site scope in common.
3455 */
3456 stc.site_scope = 1;
3457 }
3458 /* local from address */
3459 memset(&iproute6, 0, sizeof(iproute6));
3460 ro = (struct route *)&iproute6;
3461 memcpy(&ro->ro_dst, sin6, sizeof(*sin6));
4625 stc.site_scope = 1;
4626 stc.ipv4_scope = 1;
4627 } else if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
4628 /*
4629 * If the new destination is a LINK_LOCAL we
4630 * must have common both site and local
4631 * scope. Don't set local scope though since
4632 * we must depend on the source to be added

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

4656 * we must have site scope in common.
4657 */
4658 stc.site_scope = 1;
4659 }
4660 /* local from address */
4661 memset(&iproute6, 0, sizeof(iproute6));
4662 ro = (struct route *)&iproute6;
4663 memcpy(&ro->ro_dst, sin6, sizeof(*sin6));
3462 addr = sctp_ipv6_source_address_selection(inp, NULL,
3463 ro, NULL, 0);
4664 addr = sctp_source_address_selection(inp, NULL,
4665 ro, NULL, 0, vrf_id);
4666 if (addr == NULL)
4667 return;
4668
3464 if (ro->ro_rt) {
3465 RTFREE(ro->ro_rt);
4669 if (ro->ro_rt) {
4670 RTFREE(ro->ro_rt);
4671 ro->ro_rt = NULL;
3466 }
4672 }
3467 memcpy(&stc.laddress, &addr, sizeof(struct in6_addr));
4673 memcpy(&stc.laddress, &addr->address.sin6.sin6_addr, sizeof(struct in6_addr));
3468 stc.laddr_type = SCTP_IPV6_ADDRESS;
3469 }
3470 } else {
3471 /* set the scope per the existing tcb */
3472 struct sctp_nets *lnet;
3473
3474 stc.loopback_scope = asoc->loopback_scope;
3475 stc.ipv4_scope = asoc->ipv4_local_scope;

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

3496 stc.address[2] = 0;
3497 stc.address[3] = 0;
3498 stc.addr_type = SCTP_IPV4_ADDRESS;
3499 if (net->src_addr_selected == 0) {
3500 /*
3501 * strange case here, the INIT should have
3502 * did the selection.
3503 */
4674 stc.laddr_type = SCTP_IPV6_ADDRESS;
4675 }
4676 } else {
4677 /* set the scope per the existing tcb */
4678 struct sctp_nets *lnet;
4679
4680 stc.loopback_scope = asoc->loopback_scope;
4681 stc.ipv4_scope = asoc->ipv4_local_scope;

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

4702 stc.address[2] = 0;
4703 stc.address[3] = 0;
4704 stc.addr_type = SCTP_IPV4_ADDRESS;
4705 if (net->src_addr_selected == 0) {
4706 /*
4707 * strange case here, the INIT should have
4708 * did the selection.
4709 */
3504 net->ro._s_addr.sin.sin_addr =
3505 sctp_ipv4_source_address_selection(inp,
3506 stcb, (struct route *)&net->ro, net, 0);
4710 net->ro._s_addr = sctp_source_address_selection(inp,
4711 stcb, (struct route *)&net->ro,
4712 net, 0, vrf_id);
4713 if (net->ro._s_addr == NULL)
4714 return;
4715
3507 net->src_addr_selected = 1;
3508
3509 }
4716 net->src_addr_selected = 1;
4717
4718 }
3510 stc.laddress[0] = net->ro._s_addr.sin.sin_addr.s_addr;
4719 stc.laddress[0] = net->ro._s_addr->address.sin.sin_addr.s_addr;
3511 stc.laddress[1] = 0;
3512 stc.laddress[2] = 0;
3513 stc.laddress[3] = 0;
3514 stc.laddr_type = SCTP_IPV4_ADDRESS;
3515 } else if (to->sa_family == AF_INET6) {
3516 sin6 = (struct sockaddr_in6 *)to;
3517 memcpy(&stc.address, &sin6->sin6_addr,
3518 sizeof(struct in6_addr));
3519 stc.addr_type = SCTP_IPV6_ADDRESS;
3520 if (net->src_addr_selected == 0) {
3521 /*
3522 * strange case here, the INIT should have
3523 * did the selection.
3524 */
4720 stc.laddress[1] = 0;
4721 stc.laddress[2] = 0;
4722 stc.laddress[3] = 0;
4723 stc.laddr_type = SCTP_IPV4_ADDRESS;
4724 } else if (to->sa_family == AF_INET6) {
4725 sin6 = (struct sockaddr_in6 *)to;
4726 memcpy(&stc.address, &sin6->sin6_addr,
4727 sizeof(struct in6_addr));
4728 stc.addr_type = SCTP_IPV6_ADDRESS;
4729 if (net->src_addr_selected == 0) {
4730 /*
4731 * strange case here, the INIT should have
4732 * did the selection.
4733 */
3525 net->ro._s_addr.sin6.sin6_addr =
3526 sctp_ipv6_source_address_selection(inp,
3527 stcb, (struct route *)&net->ro, net, 0);
4734 net->ro._s_addr = sctp_source_address_selection(inp,
4735 stcb, (struct route *)&net->ro,
4736 net, 0, vrf_id);
4737 if (net->ro._s_addr == NULL)
4738 return;
4739
3528 net->src_addr_selected = 1;
3529 }
4740 net->src_addr_selected = 1;
4741 }
3530 memcpy(&stc.laddress, &net->ro._l_addr.sin6.sin6_addr,
4742 memcpy(&stc.laddress, &net->ro._s_addr->address.sin6.sin6_addr,
3531 sizeof(struct in6_addr));
3532 stc.laddr_type = SCTP_IPV6_ADDRESS;
3533 }
3534 }
3535 /* Now lets put the SCTP header in place */
3536 initackm_out = mtod(m, struct sctp_init_msg *);
3537 initackm_out->sh.src_port = inp->sctp_lport;
3538 initackm_out->sh.dest_port = sh->src_port;

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

3665 /* add authentication parameters */
3666 if (!sctp_auth_disable) {
3667 struct sctp_auth_random *random;
3668 struct sctp_auth_hmac_algo *hmacs;
3669 struct sctp_auth_chunk_list *chunks;
3670 uint16_t random_len;
3671
3672 /* generate and add RANDOM parameter */
4743 sizeof(struct in6_addr));
4744 stc.laddr_type = SCTP_IPV6_ADDRESS;
4745 }
4746 }
4747 /* Now lets put the SCTP header in place */
4748 initackm_out = mtod(m, struct sctp_init_msg *);
4749 initackm_out->sh.src_port = inp->sctp_lport;
4750 initackm_out->sh.dest_port = sh->src_port;

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

4877 /* add authentication parameters */
4878 if (!sctp_auth_disable) {
4879 struct sctp_auth_random *random;
4880 struct sctp_auth_hmac_algo *hmacs;
4881 struct sctp_auth_chunk_list *chunks;
4882 uint16_t random_len;
4883
4884 /* generate and add RANDOM parameter */
3673 random_len = sctp_auth_random_len;
4885 random_len = SCTP_AUTH_RANDOM_SIZE_DEFAULT;
3674 random = (struct sctp_auth_random *)(mtod(m, caddr_t)+SCTP_BUF_LEN(m));
3675 random->ph.param_type = htons(SCTP_RANDOM);
3676 p_len = sizeof(*random) + random_len;
3677 random->ph.param_length = htons(p_len);
3678 SCTP_READ_RANDOM(random->random_data, random_len);
3679 /* zero out any padding required */
3680 bzero((caddr_t)random + p_len, SCTP_SIZE32(p_len) - p_len);
3681 SCTP_BUF_LEN(m) += SCTP_SIZE32(p_len);

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

4006 siz -= sctp_get_auth_chunk_len(stcb->asoc.peer_hmac_id);
4007
4008 if (siz % 4) {
4009 /* make it an even word boundary please */
4010 siz -= (siz % 4);
4011 }
4012 return (siz);
4013}
4886 random = (struct sctp_auth_random *)(mtod(m, caddr_t)+SCTP_BUF_LEN(m));
4887 random->ph.param_type = htons(SCTP_RANDOM);
4888 p_len = sizeof(*random) + random_len;
4889 random->ph.param_length = htons(p_len);
4890 SCTP_READ_RANDOM(random->random_data, random_len);
4891 /* zero out any padding required */
4892 bzero((caddr_t)random + p_len, SCTP_SIZE32(p_len) - p_len);
4893 SCTP_BUF_LEN(m) += SCTP_SIZE32(p_len);

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

5218 siz -= sctp_get_auth_chunk_len(stcb->asoc.peer_hmac_id);
5219
5220 if (siz % 4) {
5221 /* make it an even word boundary please */
5222 siz -= (siz % 4);
5223 }
5224 return (siz);
5225}
4014extern unsigned int sctp_max_chunks_on_queue;
4015
4016static void
4017sctp_set_prsctp_policy(struct sctp_tcb *stcb,
4018 struct sctp_stream_queue_pending *sp)
4019{
4020 sp->pr_sctp_on = 0;
4021 if (stcb->asoc.peer_supports_prsctp) {
4022 /*

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

4607 mat = m;
4608 ca->sndlen = 0;
4609 while (m) {
4610 ca->sndlen += SCTP_BUF_LEN(m);
4611 m = SCTP_BUF_NEXT(m);
4612 }
4613 ca->m = m;
4614 }
5226
5227static void
5228sctp_set_prsctp_policy(struct sctp_tcb *stcb,
5229 struct sctp_stream_queue_pending *sp)
5230{
5231 sp->pr_sctp_on = 0;
5232 if (stcb->asoc.peer_supports_prsctp) {
5233 /*

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

5818 mat = m;
5819 ca->sndlen = 0;
5820 while (m) {
5821 ca->sndlen += SCTP_BUF_LEN(m);
5822 m = SCTP_BUF_NEXT(m);
5823 }
5824 ca->m = m;
5825 }
4615 ret = sctp_initiate_iterator(NULL, sctp_sendall_iterator,
5826 ret = sctp_initiate_iterator(NULL, sctp_sendall_iterator, NULL,
4616 SCTP_PCB_ANY_FLAGS, SCTP_PCB_ANY_FEATURES, SCTP_ASOC_ANY_STATE,
4617 (void *)ca, 0,
4618 sctp_sendall_completes, inp, 1);
4619 if (ret) {
4620#ifdef SCTP_DEBUG
4621 printf("Failed to initiate iterator for sendall\n");
4622#endif
4623 SCTP_FREE(ca);

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

4802 /* special handling, we must look into the param */
4803 if (chk != asoc->str_reset) {
4804 goto clean_up_anyway;
4805 }
4806 }
4807 }
4808}
4809
5827 SCTP_PCB_ANY_FLAGS, SCTP_PCB_ANY_FEATURES, SCTP_ASOC_ANY_STATE,
5828 (void *)ca, 0,
5829 sctp_sendall_completes, inp, 1);
5830 if (ret) {
5831#ifdef SCTP_DEBUG
5832 printf("Failed to initiate iterator for sendall\n");
5833#endif
5834 SCTP_FREE(ca);

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

6013 /* special handling, we must look into the param */
6014 if (chk != asoc->str_reset) {
6015 goto clean_up_anyway;
6016 }
6017 }
6018 }
6019}
6020
4810extern int sctp_min_split_point;
4811
4812static __inline int
4813sctp_can_we_split_this(struct sctp_tcb *stcb,
4814 struct sctp_stream_queue_pending *sp,
4815 int goal_mtu, int frag_point, int eeor_on)
4816{
4817 /*
4818 * Make a decision on if I should split a msg into multiple parts.

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

5189
5190}
5191
5192static void
5193sctp_fill_outqueue(struct sctp_tcb *stcb,
5194 struct sctp_nets *net, int frag_point, int eeor_mode)
5195{
5196 struct sctp_association *asoc;
6021
6022static __inline int
6023sctp_can_we_split_this(struct sctp_tcb *stcb,
6024 struct sctp_stream_queue_pending *sp,
6025 int goal_mtu, int frag_point, int eeor_on)
6026{
6027 /*
6028 * Make a decision on if I should split a msg into multiple parts.

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

6399
6400}
6401
6402static void
6403sctp_fill_outqueue(struct sctp_tcb *stcb,
6404 struct sctp_nets *net, int frag_point, int eeor_mode)
6405{
6406 struct sctp_association *asoc;
5197 struct sctp_stream_out *strq, *strqn;
6407 struct sctp_stream_out *strq, *strqn, *strqt;
5198 int goal_mtu, moved_how_much, total_moved = 0;
5199 int locked, giveup;
5200 struct sctp_stream_queue_pending *sp;
5201
5202 SCTP_TCB_LOCK_ASSERT(stcb);
5203 asoc = &stcb->asoc;
6408 int goal_mtu, moved_how_much, total_moved = 0;
6409 int locked, giveup;
6410 struct sctp_stream_queue_pending *sp;
6411
6412 SCTP_TCB_LOCK_ASSERT(stcb);
6413 asoc = &stcb->asoc;
5204#ifdef AF_INET6
6414#ifdef INET6
5205 if (net->ro._l_addr.sin6.sin6_family == AF_INET6) {
5206 goal_mtu = net->mtu - SCTP_MIN_OVERHEAD;
5207 } else {
5208 /* ?? not sure what else to do */
5209 goal_mtu = net->mtu - SCTP_MIN_V4_OVERHEAD;
5210 }
5211#else
5212 goal_mtu = net->mtu - SCTP_MIN_OVERHEAD;

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

5263 asoc->last_out_stream = strq;
5264 if (locked) {
5265 asoc->locked_on_sending = strq;
5266 if ((moved_how_much == 0) || (giveup))
5267 /* no more to move for now */
5268 break;
5269 } else {
5270 asoc->locked_on_sending = NULL;
6415 if (net->ro._l_addr.sin6.sin6_family == AF_INET6) {
6416 goal_mtu = net->mtu - SCTP_MIN_OVERHEAD;
6417 } else {
6418 /* ?? not sure what else to do */
6419 goal_mtu = net->mtu - SCTP_MIN_V4_OVERHEAD;
6420 }
6421#else
6422 goal_mtu = net->mtu - SCTP_MIN_OVERHEAD;

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

6473 asoc->last_out_stream = strq;
6474 if (locked) {
6475 asoc->locked_on_sending = strq;
6476 if ((moved_how_much == 0) || (giveup))
6477 /* no more to move for now */
6478 break;
6479 } else {
6480 asoc->locked_on_sending = NULL;
6481 strqt = sctp_select_a_stream(stcb, asoc);
5271 if (TAILQ_FIRST(&strq->outqueue) == NULL) {
5272 sctp_remove_from_wheel(stcb, asoc, strq);
5273 }
5274 if (giveup) {
5275 break;
5276 }
6482 if (TAILQ_FIRST(&strq->outqueue) == NULL) {
6483 sctp_remove_from_wheel(stcb, asoc, strq);
6484 }
6485 if (giveup) {
6486 break;
6487 }
5277 strq = sctp_select_a_stream(stcb, asoc);
6488 strq = strqt;
5278 if (strq == NULL) {
5279 break;
5280 }
5281 }
5282 total_moved += moved_how_much;
5283 goal_mtu -= moved_how_much;
5284 goal_mtu &= 0xfffffffc;
5285 }

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

5331 sctp_free_remote_addr(chk->whoTo);
5332 chk->whoTo = a_net;
5333 atomic_add_int(&a_net->ref_count, 1);
5334 }
5335 }
5336 }
5337}
5338
6489 if (strq == NULL) {
6490 break;
6491 }
6492 }
6493 total_moved += moved_how_much;
6494 goal_mtu -= moved_how_much;
6495 goal_mtu &= 0xfffffffc;
6496 }

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

6542 sctp_free_remote_addr(chk->whoTo);
6543 chk->whoTo = a_net;
6544 atomic_add_int(&a_net->ref_count, 1);
6545 }
6546 }
6547 }
6548}
6549
5339extern int sctp_early_fr;
5340
5341int
5342sctp_med_chunk_output(struct sctp_inpcb *inp,
5343 struct sctp_tcb *stcb,
5344 struct sctp_association *asoc,
5345 int *num_out,
5346 int *reason_code,
5347 int control_only, int *cwnd_full, int from_where,
5348 struct timeval *now, int *now_filled, int frag_point)

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

5359 struct sctp_nets *net;
5360 struct mbuf *outchain, *endoutchain;
5361 struct sctp_tmit_chunk *chk, *nchk;
5362 struct sctphdr *shdr;
5363
5364 /* temp arrays for unlinking */
5365 struct sctp_tmit_chunk *data_list[SCTP_MAX_DATA_BUNDLING];
5366 int no_fragmentflg, error;
6550int
6551sctp_med_chunk_output(struct sctp_inpcb *inp,
6552 struct sctp_tcb *stcb,
6553 struct sctp_association *asoc,
6554 int *num_out,
6555 int *reason_code,
6556 int control_only, int *cwnd_full, int from_where,
6557 struct timeval *now, int *now_filled, int frag_point)

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

6568 struct sctp_nets *net;
6569 struct mbuf *outchain, *endoutchain;
6570 struct sctp_tmit_chunk *chk, *nchk;
6571 struct sctphdr *shdr;
6572
6573 /* temp arrays for unlinking */
6574 struct sctp_tmit_chunk *data_list[SCTP_MAX_DATA_BUNDLING];
6575 int no_fragmentflg, error;
5367 int one_chunk, hbflag;
6576 int one_chunk, hbflag, skip_data_for_this_net;
5368 int asconf, cookie, no_out_cnt;
5369 int bundle_at, ctl_cnt, no_data_chunks, cwnd_full_ind, eeor_mode;
5370 unsigned int mtu, r_mtu, omtu, mx_mtu, to_out;
5371 struct sctp_nets *start_at, *old_startat = NULL, *send_start_at;
5372 int tsns_sent = 0;
5373 uint32_t auth_offset = 0;
5374 struct sctp_auth_chunk *auth = NULL;
5375

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

5510 * queued to this address. Skip it.
5511 */
5512 continue;
5513 }
5514 ctl_cnt = bundle_at = 0;
5515 endoutchain = outchain = NULL;
5516 no_fragmentflg = 1;
5517 one_chunk = 0;
6577 int asconf, cookie, no_out_cnt;
6578 int bundle_at, ctl_cnt, no_data_chunks, cwnd_full_ind, eeor_mode;
6579 unsigned int mtu, r_mtu, omtu, mx_mtu, to_out;
6580 struct sctp_nets *start_at, *old_startat = NULL, *send_start_at;
6581 int tsns_sent = 0;
6582 uint32_t auth_offset = 0;
6583 struct sctp_auth_chunk *auth = NULL;
6584

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

6719 * queued to this address. Skip it.
6720 */
6721 continue;
6722 }
6723 ctl_cnt = bundle_at = 0;
6724 endoutchain = outchain = NULL;
6725 no_fragmentflg = 1;
6726 one_chunk = 0;
5518
6727 if (net->dest_state & SCTP_ADDR_UNCONFIRMED) {
6728 skip_data_for_this_net = 1;
6729 } else {
6730 skip_data_for_this_net = 0;
6731 }
5519 if ((net->ro.ro_rt) && (net->ro.ro_rt->rt_ifp)) {
5520 /*
5521 * if we have a route and an ifp check to see if we
5522 * have room to send to this guy
5523 */
5524 struct ifnet *ifp;
5525
5526 ifp = net->ro.ro_rt->rt_ifp;

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

5736 if (error == EHOSTUNREACH) {
5737 /*
5738 * Destination went
5739 * unreachable
5740 * during this send
5741 */
5742 sctp_move_to_an_alt(stcb, asoc, net);
5743 }
6732 if ((net->ro.ro_rt) && (net->ro.ro_rt->rt_ifp)) {
6733 /*
6734 * if we have a route and an ifp check to see if we
6735 * have room to send to this guy
6736 */
6737 struct ifnet *ifp;
6738
6739 ifp = net->ro.ro_rt->rt_ifp;

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

6949 if (error == EHOSTUNREACH) {
6950 /*
6951 * Destination went
6952 * unreachable
6953 * during this send
6954 */
6955 sctp_move_to_an_alt(stcb, asoc, net);
6956 }
5744 sctp_clean_up_ctl(stcb, asoc);
5745 *reason_code = 7;
6957 *reason_code = 7;
5746 return (error);
6958 continue;
5747 } else
5748 asoc->ifp_had_enobuf = 0;
5749 /* Only HB or ASCONF advances time */
5750 if (hbflag) {
5751 if (*now_filled == 0) {
5752 SCTP_GETTIME_TIMEVAL(&net->last_sent_time);
5753 *now_filled = 1;
5754 *now = net->last_sent_time;

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

5799 else
5800 omtu = 0;
5801 } else {
5802 if (net->mtu > (sizeof(struct ip6_hdr) + sizeof(struct sctphdr)))
5803 omtu = net->mtu - (sizeof(struct ip6_hdr) + sizeof(struct sctphdr));
5804 else
5805 omtu = 0;
5806 }
6959 } else
6960 asoc->ifp_had_enobuf = 0;
6961 /* Only HB or ASCONF advances time */
6962 if (hbflag) {
6963 if (*now_filled == 0) {
6964 SCTP_GETTIME_TIMEVAL(&net->last_sent_time);
6965 *now_filled = 1;
6966 *now = net->last_sent_time;

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

7011 else
7012 omtu = 0;
7013 } else {
7014 if (net->mtu > (sizeof(struct ip6_hdr) + sizeof(struct sctphdr)))
7015 omtu = net->mtu - (sizeof(struct ip6_hdr) + sizeof(struct sctphdr));
7016 else
7017 omtu = 0;
7018 }
5807 if (((asoc->state & SCTP_STATE_OPEN) == SCTP_STATE_OPEN) ||
7019 if ((((asoc->state & SCTP_STATE_OPEN) == SCTP_STATE_OPEN) && (skip_data_for_this_net == 0)) ||
5808 (cookie)) {
5809 for (chk = TAILQ_FIRST(&asoc->send_queue); chk; chk = nchk) {
5810 if (no_data_chunks) {
5811 /* let only control go out */
5812 *reason_code = 1;
5813 break;
5814 }
5815 if (net->flight_size >= net->cwnd) {

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

6004 }
6005 if (error == EHOSTUNREACH) {
6006 /*
6007 * Destination went unreachable
6008 * during this send
6009 */
6010 sctp_move_to_an_alt(stcb, asoc, net);
6011 }
7020 (cookie)) {
7021 for (chk = TAILQ_FIRST(&asoc->send_queue); chk; chk = nchk) {
7022 if (no_data_chunks) {
7023 /* let only control go out */
7024 *reason_code = 1;
7025 break;
7026 }
7027 if (net->flight_size >= net->cwnd) {

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

7216 }
7217 if (error == EHOSTUNREACH) {
7218 /*
7219 * Destination went unreachable
7220 * during this send
7221 */
7222 sctp_move_to_an_alt(stcb, asoc, net);
7223 }
6012 sctp_clean_up_ctl(stcb, asoc);
6013 *reason_code = 6;
7224 *reason_code = 6;
6014 return (error);
7225 continue;
6015 } else {
6016 asoc->ifp_had_enobuf = 0;
6017 }
6018 outchain = endoutchain = NULL;
6019 auth = NULL;
6020 auth_offset = 0;
6021 if (bundle_at || hbflag) {
6022 /* For data/asconf and hb set time */

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

6902 SCTP_STAT_INCR(sctps_sendretransdata);
6903 data_list[i]->sent = SCTP_DATAGRAM_SENT;
6904 /*
6905 * When we have a revoked data, and we
6906 * retransmit it, then we clear the revoked
6907 * flag since this flag dictates if we
6908 * subtracted from the fs
6909 */
7226 } else {
7227 asoc->ifp_had_enobuf = 0;
7228 }
7229 outchain = endoutchain = NULL;
7230 auth = NULL;
7231 auth_offset = 0;
7232 if (bundle_at || hbflag) {
7233 /* For data/asconf and hb set time */

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

8113 SCTP_STAT_INCR(sctps_sendretransdata);
8114 data_list[i]->sent = SCTP_DATAGRAM_SENT;
8115 /*
8116 * When we have a revoked data, and we
8117 * retransmit it, then we clear the revoked
8118 * flag since this flag dictates if we
8119 * subtracted from the fs
8120 */
6910 data_list[i]->rec.data.chunk_was_revoked = 0;
8121 if (data_list[i]->rec.data.chunk_was_revoked) {
8122 /* Deflate the cwnd */
8123 data_list[i]->whoTo->cwnd -= data_list[i]->book_size;
8124 data_list[i]->rec.data.chunk_was_revoked = 0;
8125 }
6911 data_list[i]->snd_count++;
6912 sctp_ucount_decr(asoc->sent_queue_retran_cnt);
6913 /* record the time */
6914 data_list[i]->sent_rcv_time = asoc->time_last_sent;
6915 if (asoc->sent_queue_retran_cnt < 0) {
6916 asoc->sent_queue_retran_cnt = 0;
6917 }
6918 if (data_list[i]->book_size_scale) {

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

7521 a_chk->whoTo = NULL;
7522 break;
7523 }
7524 }
7525 if (a_chk == NULL) {
7526 sctp_alloc_a_chunk(stcb, a_chk);
7527 if (a_chk == NULL) {
7528 /* No memory so we drop the idea, and set a timer */
8126 data_list[i]->snd_count++;
8127 sctp_ucount_decr(asoc->sent_queue_retran_cnt);
8128 /* record the time */
8129 data_list[i]->sent_rcv_time = asoc->time_last_sent;
8130 if (asoc->sent_queue_retran_cnt < 0) {
8131 asoc->sent_queue_retran_cnt = 0;
8132 }
8133 if (data_list[i]->book_size_scale) {

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

8736 a_chk->whoTo = NULL;
8737 break;
8738 }
8739 }
8740 if (a_chk == NULL) {
8741 sctp_alloc_a_chunk(stcb, a_chk);
8742 if (a_chk == NULL) {
8743 /* No memory so we drop the idea, and set a timer */
7529 sctp_timer_stop(SCTP_TIMER_TYPE_RECV,
7530 stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_OUTPUT + SCTP_LOC_5);
7531 sctp_timer_start(SCTP_TIMER_TYPE_RECV,
7532 stcb->sctp_ep, stcb, NULL);
8744 if (stcb->asoc.delayed_ack) {
8745 sctp_timer_stop(SCTP_TIMER_TYPE_RECV,
8746 stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_OUTPUT + SCTP_LOC_5);
8747 sctp_timer_start(SCTP_TIMER_TYPE_RECV,
8748 stcb->sctp_ep, stcb, NULL);
8749 } else {
8750 stcb->asoc.send_sack = 1;
8751 }
7533 return;
7534 }
7535 a_chk->copy_by_ref = 0;
7536 /* a_chk->rec.chunk_id.id = SCTP_SELECTIVE_ACK; */
7537 a_chk->rec.chunk_id.id = SCTP_SELECTIVE_ACK;
7538 a_chk->rec.chunk_id.can_take_data = 1;
7539 }
8752 return;
8753 }
8754 a_chk->copy_by_ref = 0;
8755 /* a_chk->rec.chunk_id.id = SCTP_SELECTIVE_ACK; */
8756 a_chk->rec.chunk_id.id = SCTP_SELECTIVE_ACK;
8757 a_chk->rec.chunk_id.can_take_data = 1;
8758 }
8759 /* Clear our pkt counts */
8760 asoc->data_pkts_seen = 0;
8761
7540 a_chk->asoc = asoc;
7541 a_chk->snd_count = 0;
7542 a_chk->send_size = 0; /* fill in later */
7543 a_chk->sent = SCTP_DATAGRAM_UNSENT;
7544
7545 if ((asoc->numduptsns) ||
7546 (asoc->last_data_chunk_from->dest_state & SCTP_ADDR_NOT_REACHABLE)
7547 ) {

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

7590 if (a_chk->data) {
7591 /* was a problem with the destination */
7592 sctp_m_freem(a_chk->data);
7593 a_chk->data = NULL;
7594 }
7595 if (a_chk->whoTo)
7596 atomic_subtract_int(&a_chk->whoTo->ref_count, 1);
7597 sctp_free_a_chunk(stcb, a_chk);
8762 a_chk->asoc = asoc;
8763 a_chk->snd_count = 0;
8764 a_chk->send_size = 0; /* fill in later */
8765 a_chk->sent = SCTP_DATAGRAM_UNSENT;
8766
8767 if ((asoc->numduptsns) ||
8768 (asoc->last_data_chunk_from->dest_state & SCTP_ADDR_NOT_REACHABLE)
8769 ) {

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

8812 if (a_chk->data) {
8813 /* was a problem with the destination */
8814 sctp_m_freem(a_chk->data);
8815 a_chk->data = NULL;
8816 }
8817 if (a_chk->whoTo)
8818 atomic_subtract_int(&a_chk->whoTo->ref_count, 1);
8819 sctp_free_a_chunk(stcb, a_chk);
7598 sctp_timer_stop(SCTP_TIMER_TYPE_RECV,
7599 stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_OUTPUT + SCTP_LOC_6);
7600 sctp_timer_start(SCTP_TIMER_TYPE_RECV,
7601 stcb->sctp_ep, stcb, NULL);
8820 if (stcb->asoc.delayed_ack) {
8821 sctp_timer_stop(SCTP_TIMER_TYPE_RECV,
8822 stcb->sctp_ep, stcb, NULL, SCTP_FROM_SCTP_OUTPUT + SCTP_LOC_6);
8823 sctp_timer_start(SCTP_TIMER_TYPE_RECV,
8824 stcb->sctp_ep, stcb, NULL);
8825 } else {
8826 stcb->asoc.send_sack = 1;
8827 }
7602 return;
7603 }
7604 /* ok, lets go through and fill it in */
7605 SCTP_BUF_RESV_UF(a_chk->data, SCTP_MIN_OVERHEAD);
7606 space = M_TRAILINGSPACE(a_chk->data);
7607 if (space > (a_chk->whoTo->mtu - SCTP_MIN_OVERHEAD)) {
7608 space = (a_chk->whoTo->mtu - SCTP_MIN_OVERHEAD);
7609 }

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

7732 (num_gap_blocks * sizeof(struct sctp_gap_ack_block)) +
7733 (num_dups * sizeof(int32_t)));
7734 SCTP_BUF_LEN(a_chk->data) = a_chk->send_size;
7735 sack->sack.num_gap_ack_blks = htons(num_gap_blocks);
7736 sack->sack.num_dup_tsns = htons(num_dups);
7737 sack->ch.chunk_length = htons(a_chk->send_size);
7738 TAILQ_INSERT_TAIL(&asoc->control_send_queue, a_chk, sctp_next);
7739 asoc->ctrl_queue_cnt++;
8828 return;
8829 }
8830 /* ok, lets go through and fill it in */
8831 SCTP_BUF_RESV_UF(a_chk->data, SCTP_MIN_OVERHEAD);
8832 space = M_TRAILINGSPACE(a_chk->data);
8833 if (space > (a_chk->whoTo->mtu - SCTP_MIN_OVERHEAD)) {
8834 space = (a_chk->whoTo->mtu - SCTP_MIN_OVERHEAD);
8835 }

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

8958 (num_gap_blocks * sizeof(struct sctp_gap_ack_block)) +
8959 (num_dups * sizeof(int32_t)));
8960 SCTP_BUF_LEN(a_chk->data) = a_chk->send_size;
8961 sack->sack.num_gap_ack_blks = htons(num_gap_blocks);
8962 sack->sack.num_dup_tsns = htons(num_dups);
8963 sack->ch.chunk_length = htons(a_chk->send_size);
8964 TAILQ_INSERT_TAIL(&asoc->control_send_queue, a_chk, sctp_next);
8965 asoc->ctrl_queue_cnt++;
8966 asoc->send_sack = 0;
7740 SCTP_STAT_INCR(sctps_sendsacks);
7741 return;
7742}
7743
7744
7745void
7746sctp_send_abort_tcb(struct sctp_tcb *stcb, struct mbuf *operr)
7747{

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

9209 }
9210 }
9211 error = sctp_lower_sosend(so, addr, uio, top, control, flags,
9212 use_rcvinfo, &srcv, p);
9213 return (error);
9214}
9215
9216
8967 SCTP_STAT_INCR(sctps_sendsacks);
8968 return;
8969}
8970
8971
8972void
8973sctp_send_abort_tcb(struct sctp_tcb *stcb, struct mbuf *operr)
8974{

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

10436 }
10437 }
10438 error = sctp_lower_sosend(so, addr, uio, top, control, flags,
10439 use_rcvinfo, &srcv, p);
10440 return (error);
10441}
10442
10443
9217extern unsigned int sctp_add_more_threshold;
9218int
9219sctp_lower_sosend(struct socket *so,
9220 struct sockaddr *addr,
9221 struct uio *uio,
9222 struct mbuf *i_pak,
9223 struct mbuf *control,
9224 int flags,
9225 int use_rcvinfo,

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

9376 } else if (addr == NULL) {
9377 error = ENOENT;
9378 goto out_unlocked;
9379 } else {
9380 /*
9381 * UDP style, we must go ahead and start the INIT
9382 * process
9383 */
10444int
10445sctp_lower_sosend(struct socket *so,
10446 struct sockaddr *addr,
10447 struct uio *uio,
10448 struct mbuf *i_pak,
10449 struct mbuf *control,
10450 int flags,
10451 int use_rcvinfo,

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

10602 } else if (addr == NULL) {
10603 error = ENOENT;
10604 goto out_unlocked;
10605 } else {
10606 /*
10607 * UDP style, we must go ahead and start the INIT
10608 * process
10609 */
10610 uint32_t vrf;
10611
9384 if ((use_rcvinfo) && (srcv) &&
9385 ((srcv->sinfo_flags & SCTP_ABORT) ||
9386 ((srcv->sinfo_flags & SCTP_EOF) &&
9387 (uio->uio_resid == 0)))) {
9388 /*
9389 * User asks to abort a non-existant assoc,
9390 * or EOF a non-existant assoc with no data
9391 */
9392 error = ENOENT;
9393 goto out_unlocked;
9394 }
9395 /* get an asoc/stcb struct */
10612 if ((use_rcvinfo) && (srcv) &&
10613 ((srcv->sinfo_flags & SCTP_ABORT) ||
10614 ((srcv->sinfo_flags & SCTP_EOF) &&
10615 (uio->uio_resid == 0)))) {
10616 /*
10617 * User asks to abort a non-existant assoc,
10618 * or EOF a non-existant assoc with no data
10619 */
10620 error = ENOENT;
10621 goto out_unlocked;
10622 }
10623 /* get an asoc/stcb struct */
9396 stcb = sctp_aloc_assoc(inp, addr, 1, &error, 0);
10624 vrf = SCTP_DEFAULT_VRFID;
10625 stcb = sctp_aloc_assoc(inp, addr, 1, &error, 0, vrf);
9397 if (stcb == NULL) {
9398 /* Error is setup for us in the call */
9399 goto out_unlocked;
9400 }
9401 if (create_lock_applied) {
9402 SCTP_ASOC_CREATE_UNLOCK(inp);
9403 create_lock_applied = 0;
9404 } else {

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

9517 * but the ro structure may now have an update and
9518 * thus we may need to change it BEFORE we append
9519 * the message.
9520 */
9521 net = stcb->asoc.primary_destination;
9522 asoc = &stcb->asoc;
9523 }
9524 }
10626 if (stcb == NULL) {
10627 /* Error is setup for us in the call */
10628 goto out_unlocked;
10629 }
10630 if (create_lock_applied) {
10631 SCTP_ASOC_CREATE_UNLOCK(inp);
10632 create_lock_applied = 0;
10633 } else {

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

10746 * but the ro structure may now have an update and
10747 * thus we may need to change it BEFORE we append
10748 * the message.
10749 */
10750 net = stcb->asoc.primary_destination;
10751 asoc = &stcb->asoc;
10752 }
10753 }
9525 if (((so->so_state & SS_NBIO)
10754 if ((SCTP_SO_IS_NBIO(so)
9526 || (flags & MSG_NBIO)
9527 )) {
9528 non_blocking = 1;
9529 }
9530 asoc = &stcb->asoc;
9531 /* would we block? */
9532 if (non_blocking) {
9533 if ((so->so_snd.sb_hiwat <

--- 858 unchanged lines hidden ---
10755 || (flags & MSG_NBIO)
10756 )) {
10757 non_blocking = 1;
10758 }
10759 asoc = &stcb->asoc;
10760 /* would we block? */
10761 if (non_blocking) {
10762 if ((so->so_snd.sb_hiwat <

--- 858 unchanged lines hidden ---