sctputil.c (165647) | sctputil.c (166023) |
---|---|
1/*- 2 * Copyright (c) 2001-2006, 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-2006, 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 165647 2006-12-29 20:21:42Z rrs $"); | 34__FBSDID("$FreeBSD: head/sys/netinet/sctputil.c 166023 2007-01-15 15:12:10Z rrs $"); |
35 36 37#include "opt_ipsec.h" 38#include "opt_compat.h" 39#include "opt_inet6.h" 40#include "opt_inet.h" 41#include "opt_sctp.h" 42 --- 1032 unchanged lines hidden (view full) --- 1075 asoc->nonce_wait_tsn = 0; 1076 asoc->delayed_ack = TICKS_TO_MSEC(m->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV]); 1077 asoc->pr_sctp_cnt = 0; 1078 asoc->total_output_queue_size = 0; 1079 1080 if (m->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 1081 struct in6pcb *inp6; 1082 | 35 36 37#include "opt_ipsec.h" 38#include "opt_compat.h" 39#include "opt_inet6.h" 40#include "opt_inet.h" 41#include "opt_sctp.h" 42 --- 1032 unchanged lines hidden (view full) --- 1075 asoc->nonce_wait_tsn = 0; 1076 asoc->delayed_ack = TICKS_TO_MSEC(m->sctp_ep.sctp_timeoutticks[SCTP_TIMER_RECV]); 1077 asoc->pr_sctp_cnt = 0; 1078 asoc->total_output_queue_size = 0; 1079 1080 if (m->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) { 1081 struct in6pcb *inp6; 1082 |
1083 | |
1084 /* Its a V6 socket */ 1085 inp6 = (struct in6pcb *)m; 1086 asoc->ipv6_addr_legal = 1; 1087 /* Now look at the binding flag to see if V4 will be legal */ | 1083 /* Its a V6 socket */ 1084 inp6 = (struct in6pcb *)m; 1085 asoc->ipv6_addr_legal = 1; 1086 /* Now look at the binding flag to see if V4 will be legal */ |
1088 if ( 1089 (inp6->inp_flags & IN6P_IPV6_V6ONLY) 1090 == 0) { | 1087 if (SCTP_IPV6_V6ONLY(inp6) == 0) { |
1091 asoc->ipv4_addr_legal = 1; 1092 } else { 1093 /* V4 addresses are NOT legal on the association */ 1094 asoc->ipv4_addr_legal = 0; 1095 } 1096 } else { 1097 /* Its a V4 socket, no - V6 */ 1098 asoc->ipv4_addr_legal = 1; 1099 asoc->ipv6_addr_legal = 0; 1100 } 1101 | 1088 asoc->ipv4_addr_legal = 1; 1089 } else { 1090 /* V4 addresses are NOT legal on the association */ 1091 asoc->ipv4_addr_legal = 0; 1092 } 1093 } else { 1094 /* Its a V4 socket, no - V6 */ 1095 asoc->ipv4_addr_legal = 1; 1096 asoc->ipv6_addr_legal = 0; 1097 } 1098 |
1102 | |
1103 asoc->my_rwnd = max(m->sctp_socket->so_rcv.sb_hiwat, SCTP_MINIMAL_RWND); 1104 asoc->peers_rwnd = m->sctp_socket->so_rcv.sb_hiwat; 1105 1106 asoc->smallest_mtu = m->sctp_frag_point; 1107 asoc->minrto = m->sctp_ep.sctp_minrto; 1108 asoc->maxrto = m->sctp_ep.sctp_maxrto; 1109 1110 asoc->locked_on_sending = NULL; --- 210 unchanged lines hidden (view full) --- 1321 if (!SCTP_OS_TIMER_ACTIVE(&tmr->timer)) { 1322 splx(s); 1323 if (inp) { 1324 SCTP_INP_DECR_REF(inp); 1325 } 1326 return; 1327 } 1328 tmr->stopped_from = 0xa006; | 1099 asoc->my_rwnd = max(m->sctp_socket->so_rcv.sb_hiwat, SCTP_MINIMAL_RWND); 1100 asoc->peers_rwnd = m->sctp_socket->so_rcv.sb_hiwat; 1101 1102 asoc->smallest_mtu = m->sctp_frag_point; 1103 asoc->minrto = m->sctp_ep.sctp_minrto; 1104 asoc->maxrto = m->sctp_ep.sctp_maxrto; 1105 1106 asoc->locked_on_sending = NULL; --- 210 unchanged lines hidden (view full) --- 1317 if (!SCTP_OS_TIMER_ACTIVE(&tmr->timer)) { 1318 splx(s); 1319 if (inp) { 1320 SCTP_INP_DECR_REF(inp); 1321 } 1322 return; 1323 } 1324 tmr->stopped_from = 0xa006; |
1329 /* record in stopped what t-o occured */ 1330 tmr->stopped_from = tmr->type; | |
1331 1332 if (stcb) { 1333 atomic_add_int(&stcb->asoc.refcnt, 1); 1334 SCTP_TCB_LOCK(stcb); 1335 atomic_add_int(&stcb->asoc.refcnt, -1); 1336 } | 1325 1326 if (stcb) { 1327 atomic_add_int(&stcb->asoc.refcnt, 1); 1328 SCTP_TCB_LOCK(stcb); 1329 atomic_add_int(&stcb->asoc.refcnt, -1); 1330 } |
1331 /* record in stopped what t-o occured */ 1332 tmr->stopped_from = tmr->type; 1333 |
|
1337 /* mark as being serviced now */ | 1334 /* mark as being serviced now */ |
1335 if (SCTP_OS_TIMER_PENDING(&tmr->timer)) { 1336 /* 1337 * Callout has been rescheduled. 1338 */ 1339 goto get_out; 1340 } 1341 if (!SCTP_OS_TIMER_ACTIVE(&tmr->timer)) { 1342 /* 1343 * Not active, so no action. 1344 */ 1345 goto get_out; 1346 } |
|
1338 SCTP_OS_TIMER_DEACTIVATE(&tmr->timer); 1339 1340 /* call the handler for the appropriate timer type */ 1341 switch (tmr->type) { 1342 case SCTP_TIMER_TYPE_ADDR_WQ: 1343 sctp_handle_addr_wq(); 1344 break; 1345 case SCTP_TIMER_TYPE_ITERATOR: --- 224 unchanged lines hidden (view full) --- 1570 * Now we need to clean up the control chunk chain if an 1571 * ECNE is on it. It must be marked as UNSENT again so next 1572 * call will continue to send it until such time that we get 1573 * a CWR, to remove it. It is, however, less likely that we 1574 * will find a ecn echo on the chain though. 1575 */ 1576 sctp_fix_ecn_echo(&stcb->asoc); 1577 } | 1347 SCTP_OS_TIMER_DEACTIVATE(&tmr->timer); 1348 1349 /* call the handler for the appropriate timer type */ 1350 switch (tmr->type) { 1351 case SCTP_TIMER_TYPE_ADDR_WQ: 1352 sctp_handle_addr_wq(); 1353 break; 1354 case SCTP_TIMER_TYPE_ITERATOR: --- 224 unchanged lines hidden (view full) --- 1579 * Now we need to clean up the control chunk chain if an 1580 * ECNE is on it. It must be marked as UNSENT again so next 1581 * call will continue to send it until such time that we get 1582 * a CWR, to remove it. It is, however, less likely that we 1583 * will find a ecn echo on the chain though. 1584 */ 1585 sctp_fix_ecn_echo(&stcb->asoc); 1586 } |
1587get_out: |
|
1578 if (stcb) { 1579 SCTP_TCB_UNLOCK(stcb); 1580 } 1581out_decr: 1582 if (inp) { 1583 SCTP_INP_DECR_REF(inp); 1584 } 1585out_no_decr: --- 708 unchanged lines hidden (view full) --- 2294 return (base); 2295} 2296 2297 2298#endif 2299 2300void 2301sctp_mtu_size_reset(struct sctp_inpcb *inp, | 1588 if (stcb) { 1589 SCTP_TCB_UNLOCK(stcb); 1590 } 1591out_decr: 1592 if (inp) { 1593 SCTP_INP_DECR_REF(inp); 1594 } 1595out_no_decr: --- 708 unchanged lines hidden (view full) --- 2304 return (base); 2305} 2306 2307 2308#endif 2309 2310void 2311sctp_mtu_size_reset(struct sctp_inpcb *inp, |
2302 struct sctp_association *asoc, u_long mtu) | 2312 struct sctp_association *asoc, uint32_t mtu) |
2303{ 2304 /* 2305 * Reset the P-MTU size on this association, this involves changing 2306 * the asoc MTU, going through ANY chunk+overhead larger than mtu to 2307 * allow the DF flag to be cleared. 2308 */ 2309 struct sctp_tmit_chunk *chk; 2310 unsigned int eff_mtu, ovh; --- 134 unchanged lines hidden (view full) --- 2445 } 2446 if (new_rto > stcb->asoc.maxrto) { 2447 new_rto = stcb->asoc.maxrto; 2448 } 2449 /* we are now returning the RTT Smoothed */ 2450 return ((uint32_t) new_rto); 2451} 2452 | 2313{ 2314 /* 2315 * Reset the P-MTU size on this association, this involves changing 2316 * the asoc MTU, going through ANY chunk+overhead larger than mtu to 2317 * allow the DF flag to be cleared. 2318 */ 2319 struct sctp_tmit_chunk *chk; 2320 unsigned int eff_mtu, ovh; --- 134 unchanged lines hidden (view full) --- 2455 } 2456 if (new_rto > stcb->asoc.maxrto) { 2457 new_rto = stcb->asoc.maxrto; 2458 } 2459 /* we are now returning the RTT Smoothed */ 2460 return ((uint32_t) new_rto); 2461} 2462 |
2453 | |
2454/* 2455 * return a pointer to a contiguous piece of data from the given mbuf chain 2456 * starting at 'off' for 'len' bytes. If the desired piece spans more than 2457 * one mbuf, a copy is made at 'ptr'. caller must ensure that the buffer size 2458 * is >= 'len' returns NULL if there there isn't 'len' bytes in the chain. 2459 */ 2460__inline caddr_t 2461sctp_m_getptr(struct mbuf *m, int off, int len, uint8_t * in_ptr) --- 31 unchanged lines hidden (view full) --- 2493 if ((m == NULL) && (len > 0)) 2494 return (NULL); 2495 else 2496 return ((caddr_t)in_ptr); 2497 } 2498} 2499 2500 | 2463/* 2464 * return a pointer to a contiguous piece of data from the given mbuf chain 2465 * starting at 'off' for 'len' bytes. If the desired piece spans more than 2466 * one mbuf, a copy is made at 'ptr'. caller must ensure that the buffer size 2467 * is >= 'len' returns NULL if there there isn't 'len' bytes in the chain. 2468 */ 2469__inline caddr_t 2470sctp_m_getptr(struct mbuf *m, int off, int len, uint8_t * in_ptr) --- 31 unchanged lines hidden (view full) --- 2502 if ((m == NULL) && (len > 0)) 2503 return (NULL); 2504 else 2505 return ((caddr_t)in_ptr); 2506 } 2507} 2508 2509 |
2510 |
|
2501struct sctp_paramhdr * 2502sctp_get_next_param(struct mbuf *m, 2503 int offset, 2504 struct sctp_paramhdr *pull, 2505 int pull_limit) 2506{ 2507 /* This just provides a typed signature to Peter's Pull routine */ 2508 return ((struct sctp_paramhdr *)sctp_m_getptr(m, offset, pull_limit, --- 88 unchanged lines hidden (view full) --- 2597 } 2598 /* 2599 * For TCP model AND UDP connected sockets we will send an error up 2600 * when an ABORT comes in. 2601 */ 2602 if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 2603 (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) && 2604 (event == SCTP_COMM_LOST)) { | 2511struct sctp_paramhdr * 2512sctp_get_next_param(struct mbuf *m, 2513 int offset, 2514 struct sctp_paramhdr *pull, 2515 int pull_limit) 2516{ 2517 /* This just provides a typed signature to Peter's Pull routine */ 2518 return ((struct sctp_paramhdr *)sctp_m_getptr(m, offset, pull_limit, --- 88 unchanged lines hidden (view full) --- 2607 } 2608 /* 2609 * For TCP model AND UDP connected sockets we will send an error up 2610 * when an ABORT comes in. 2611 */ 2612 if (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 2613 (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) && 2614 (event == SCTP_COMM_LOST)) { |
2605 if (TAILQ_EMPTY(&stcb->sctp_ep->read_queue)) { | 2615 if (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_COOKIE_WAIT) 2616 stcb->sctp_socket->so_error = ECONNREFUSED; 2617 else |
2606 stcb->sctp_socket->so_error = ECONNRESET; | 2618 stcb->sctp_socket->so_error = ECONNRESET; |
2607 } | |
2608 /* Wake ANY sleepers */ 2609 sorwakeup(stcb->sctp_socket); 2610 sowwakeup(stcb->sctp_socket); 2611 sctp_asoc_change_wake++; 2612 } 2613 if (sctp_is_feature_off(stcb->sctp_ep, SCTP_PCB_FLAGS_RECVASSOCEVNT)) { 2614 /* event not enabled */ 2615 return; --- 1023 unchanged lines hidden (view full) --- 3639 fsa6.sin6_port = sh->dest_port; 3640 printf("src: "); 3641 sctp_print_address((struct sockaddr *)&lsa6); 3642 printf("dest: "); 3643 sctp_print_address((struct sockaddr *)&fsa6); 3644 } 3645} 3646 | 2619 /* Wake ANY sleepers */ 2620 sorwakeup(stcb->sctp_socket); 2621 sowwakeup(stcb->sctp_socket); 2622 sctp_asoc_change_wake++; 2623 } 2624 if (sctp_is_feature_off(stcb->sctp_ep, SCTP_PCB_FLAGS_RECVASSOCEVNT)) { 2625 /* event not enabled */ 2626 return; --- 1023 unchanged lines hidden (view full) --- 3650 fsa6.sin6_port = sh->dest_port; 3651 printf("src: "); 3652 sctp_print_address((struct sockaddr *)&lsa6); 3653 printf("dest: "); 3654 sctp_print_address((struct sockaddr *)&fsa6); 3655 } 3656} 3657 |
3647#if defined(HAVE_SCTP_SO_LASTRECORD) 3648 3649/* cloned from uipc_socket.c */ 3650 3651#define SCTP_SBLINKRECORD(sb, m0) do { \ 3652 if ((sb)->sb_lastrecord != NULL) \ 3653 SCTP_BUF_NEXT_PKT((sb)->sb_lastrecord) = (m0); \ 3654 else \ 3655 (sb)->sb_mb = (m0); \ 3656 (sb)->sb_lastrecord = (m0); \ 3657} while (/*CONSTCOND*/0) 3658#endif 3659 | |
3660void 3661sctp_pull_off_control_to_new_inp(struct sctp_inpcb *old_inp, 3662 struct sctp_inpcb *new_inp, 3663 struct sctp_tcb *stcb) 3664{ 3665 /* 3666 * go through our old INP and pull off any control structures that 3667 * belong to stcb and move then to the new inp. --- 307 unchanged lines hidden (view full) --- 3975 } 3976 asoc->chunks_on_out_queue -= chk_cnt; 3977 sctp_log_mbcnt(SCTP_LOG_MBCNT_DECREASE, 3978 asoc->total_output_queue_size, 3979 tp1->book_size, 3980 0, 3981 tp1->mbcnt); 3982 if (asoc->total_output_queue_size >= tp1->book_size) { | 3658void 3659sctp_pull_off_control_to_new_inp(struct sctp_inpcb *old_inp, 3660 struct sctp_inpcb *new_inp, 3661 struct sctp_tcb *stcb) 3662{ 3663 /* 3664 * go through our old INP and pull off any control structures that 3665 * belong to stcb and move then to the new inp. --- 307 unchanged lines hidden (view full) --- 3973 } 3974 asoc->chunks_on_out_queue -= chk_cnt; 3975 sctp_log_mbcnt(SCTP_LOG_MBCNT_DECREASE, 3976 asoc->total_output_queue_size, 3977 tp1->book_size, 3978 0, 3979 tp1->mbcnt); 3980 if (asoc->total_output_queue_size >= tp1->book_size) { |
3983 asoc->total_output_queue_size -= tp1->book_size; | 3981 atomic_add_int(&asoc->total_output_queue_size, -tp1->book_size); |
3984 } else { 3985 asoc->total_output_queue_size = 0; 3986 } 3987 3988 if (stcb->sctp_socket && (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) || 3989 ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE)))) { 3990 if (stcb->sctp_socket->so_snd.sb_cc >= tp1->book_size) { 3991 stcb->sctp_socket->so_snd.sb_cc -= tp1->book_size; --- 328 unchanged lines hidden (view full) --- 4320 if (hold_sblock == 0) { 4321 SOCKBUF_LOCK(&so->so_rcv); 4322 hold_sblock = 1; 4323 } 4324 if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) || 4325 (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE)) { 4326 goto out; 4327 } | 3982 } else { 3983 asoc->total_output_queue_size = 0; 3984 } 3985 3986 if (stcb->sctp_socket && (((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) || 3987 ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE)))) { 3988 if (stcb->sctp_socket->so_snd.sb_cc >= tp1->book_size) { 3989 stcb->sctp_socket->so_snd.sb_cc -= tp1->book_size; --- 328 unchanged lines hidden (view full) --- 4318 if (hold_sblock == 0) { 4319 SOCKBUF_LOCK(&so->so_rcv); 4320 hold_sblock = 1; 4321 } 4322 if ((inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) || 4323 (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_ALLGONE)) { 4324 goto out; 4325 } |
4328 if (so->so_error || so->so_rcv.sb_state & SBS_CANTRCVMORE) { | 4326 if (so->so_rcv.sb_state & SBS_CANTRCVMORE) { |
4329 if (so->so_error) { 4330 error = so->so_error; | 4327 if (so->so_error) { 4328 error = so->so_error; |
4329 if ((in_flags & MSG_PEEK) == 0) 4330 so->so_error = 0; |
|
4331 } else { 4332 error = ENOTCONN; 4333 } 4334 goto out; 4335 } 4336 if ((so->so_rcv.sb_cc <= held_length) && block_allowed) { 4337 /* we need to wait for data */ 4338#ifdef SCTP_RECV_DETAIL_RWND_LOGGING --- 43 unchanged lines hidden (view full) --- 4382 } 4383 error = sbwait(&so->so_rcv); 4384 if (error) { 4385 goto out; 4386 } 4387 held_length = 0; 4388 goto restart_nosblocks; 4389 } else if (so->so_rcv.sb_cc == 0) { | 4331 } else { 4332 error = ENOTCONN; 4333 } 4334 goto out; 4335 } 4336 if ((so->so_rcv.sb_cc <= held_length) && block_allowed) { 4337 /* we need to wait for data */ 4338#ifdef SCTP_RECV_DETAIL_RWND_LOGGING --- 43 unchanged lines hidden (view full) --- 4382 } 4383 error = sbwait(&so->so_rcv); 4384 if (error) { 4385 goto out; 4386 } 4387 held_length = 0; 4388 goto restart_nosblocks; 4389 } else if (so->so_rcv.sb_cc == 0) { |
4390 error = EWOULDBLOCK; | 4390 if (so->so_error) { 4391 error = so->so_error; 4392 if ((in_flags & MSG_PEEK) == 0) 4393 so->so_error = 0; 4394 } else { 4395 if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) || 4396 (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) { 4397 if ((inp->sctp_flags & SCTP_PCB_FLAGS_CONNECTED) == 0) { 4398 /* 4399 * For active open side clear flags 4400 * for re-use passive open is 4401 * blocked by connect. 4402 */ 4403 if (inp->sctp_flags & SCTP_PCB_FLAGS_WAS_ABORTED) { 4404 /* 4405 * You were aborted, passive 4406 * side always hits here 4407 */ 4408 error = ECONNRESET; 4409 /* 4410 * You get this once if you 4411 * are active open side 4412 */ 4413 if (!(inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL)) { 4414 /* 4415 * Remove flag if on 4416 * the active open 4417 * side 4418 */ 4419 inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAS_ABORTED; 4420 } 4421 } 4422 so->so_state &= ~(SS_ISCONNECTING | 4423 SS_ISDISCONNECTING | 4424 SS_ISCONFIRMING | 4425 SS_ISCONNECTED); 4426 if (error == 0) { 4427 if ((inp->sctp_flags & SCTP_PCB_FLAGS_WAS_CONNECTED) == 0) { 4428 error = ENOTCONN; 4429 } else { 4430 inp->sctp_flags &= ~SCTP_PCB_FLAGS_WAS_CONNECTED; 4431 } 4432 } 4433 goto out; 4434 } 4435 } 4436 error = EWOULDBLOCK; 4437 } |
4391 goto out; 4392 } 4393 error = sblock(&so->so_rcv, (block_allowed ? M_WAITOK : 0)); 4394 /* we possibly have data we can read */ 4395 control = TAILQ_FIRST(&inp->read_queue); 4396 if (control == NULL) { 4397 /* 4398 * This could be happening since the appender did the --- 502 unchanged lines hidden (view full) --- 4901 */ 4902 if (((stcb) && (in_flags & MSG_PEEK) == 0) && 4903 ((freed_so_far >= rwnd_req) && 4904 (control->do_not_ref_stcb == 0) && 4905 (no_rcv_needed == 0))) { 4906 sctp_user_rcvd(stcb, &freed_so_far, hold_rlock, rwnd_req); 4907 } 4908wait_some_more: | 4438 goto out; 4439 } 4440 error = sblock(&so->so_rcv, (block_allowed ? M_WAITOK : 0)); 4441 /* we possibly have data we can read */ 4442 control = TAILQ_FIRST(&inp->read_queue); 4443 if (control == NULL) { 4444 /* 4445 * This could be happening since the appender did the --- 502 unchanged lines hidden (view full) --- 4948 */ 4949 if (((stcb) && (in_flags & MSG_PEEK) == 0) && 4950 ((freed_so_far >= rwnd_req) && 4951 (control->do_not_ref_stcb == 0) && 4952 (no_rcv_needed == 0))) { 4953 sctp_user_rcvd(stcb, &freed_so_far, hold_rlock, rwnd_req); 4954 } 4955wait_some_more: |
4909 if (so->so_error || so->so_rcv.sb_state & SBS_CANTRCVMORE) { | 4956 if (so->so_rcv.sb_state & SBS_CANTRCVMORE) { |
4910 goto release; 4911 } 4912 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) 4913 goto release; 4914 4915 if (hold_rlock == 1) { 4916 SCTP_INP_READ_UNLOCK(inp); 4917 hold_rlock = 0; --- 111 unchanged lines hidden (view full) --- 5029 } 5030 /* still more to do with this conntrol */ 5031 /* do we really support msg_waitall here? */ 5032 if ((block_allowed == 0) || 5033 ((in_flags & MSG_WAITALL) == 0)) { 5034 goto release; 5035 } 5036 wait_some_more2: | 4957 goto release; 4958 } 4959 if (inp->sctp_flags & SCTP_PCB_FLAGS_SOCKET_GONE) 4960 goto release; 4961 4962 if (hold_rlock == 1) { 4963 SCTP_INP_READ_UNLOCK(inp); 4964 hold_rlock = 0; --- 111 unchanged lines hidden (view full) --- 5076 } 5077 /* still more to do with this conntrol */ 5078 /* do we really support msg_waitall here? */ 5079 if ((block_allowed == 0) || 5080 ((in_flags & MSG_WAITALL) == 0)) { 5081 goto release; 5082 } 5083 wait_some_more2: |
5037 if (so->so_error || so->so_rcv.sb_state & SBS_CANTRCVMORE) | 5084 if (so->so_rcv.sb_state & SBS_CANTRCVMORE) |
5038 goto release; 5039 if (hold_rlock == 1) { 5040 SCTP_INP_READ_UNLOCK(inp); 5041 hold_rlock = 0; 5042 } 5043 if (hold_sblock == 0) { 5044 SOCKBUF_LOCK(&so->so_rcv); 5045 hold_sblock = 1; --- 77 unchanged lines hidden (view full) --- 5123 SCTP_INP_READ_UNLOCK(inp); 5124 hold_rlock = 0; 5125 } 5126 if (hold_sblock) { 5127 SOCKBUF_UNLOCK(&so->so_rcv); 5128 hold_sblock = 0; 5129 } 5130 splx(s); | 5085 goto release; 5086 if (hold_rlock == 1) { 5087 SCTP_INP_READ_UNLOCK(inp); 5088 hold_rlock = 0; 5089 } 5090 if (hold_sblock == 0) { 5091 SOCKBUF_LOCK(&so->so_rcv); 5092 hold_sblock = 1; --- 77 unchanged lines hidden (view full) --- 5170 SCTP_INP_READ_UNLOCK(inp); 5171 hold_rlock = 0; 5172 } 5173 if (hold_sblock) { 5174 SOCKBUF_UNLOCK(&so->so_rcv); 5175 hold_sblock = 0; 5176 } 5177 splx(s); |
5131 *mp = sctp_m_copym(m, 0, cp_len, | 5178 *mp = SCTP_M_COPYM(m, 0, cp_len, |
5132 M_TRYWAIT 5133 ); 5134 s = splnet(); 5135#ifdef SCTP_LOCK_LOGGING 5136 sctp_log_lock(inp, stcb, SCTP_LOG_LOCK_SOCKBUF_R); 5137#endif 5138 if (hold_sblock == 0) { 5139 SOCKBUF_LOCK(&so->so_rcv); --- 179 unchanged lines hidden --- | 5179 M_TRYWAIT 5180 ); 5181 s = splnet(); 5182#ifdef SCTP_LOCK_LOGGING 5183 sctp_log_lock(inp, stcb, SCTP_LOG_LOCK_SOCKBUF_R); 5184#endif 5185 if (hold_sblock == 0) { 5186 SOCKBUF_LOCK(&so->so_rcv); --- 179 unchanged lines hidden --- |