summaryrefslogtreecommitdiffstats
path: root/sys/netinet/sctputil.c
diff options
context:
space:
mode:
authorrrs <rrs@FreeBSD.org>2007-05-02 12:50:13 +0000
committerrrs <rrs@FreeBSD.org>2007-05-02 12:50:13 +0000
commit803b9be8be0827d6f2fde839f6dcd9225a2609be (patch)
tree93ea4f957056813b10463b788259dc0304a365e3 /sys/netinet/sctputil.c
parent78898ea5a86dc4f5a06f63d1f2c50c2c6497bef9 (diff)
downloadFreeBSD-src-803b9be8be0827d6f2fde839f6dcd9225a2609be.zip
FreeBSD-src-803b9be8be0827d6f2fde839f6dcd9225a2609be.tar.gz
- Somehow the disable fragment option got lost. We could
set/clear it but would not do it. Now we will. - Moved to latest socket api for extended sndrcv info struct. - Moved to support all new levels of fragment interleave (0-2). - Codenomicon security test updates - length checks and such. - Bug in stream reset (2 actually). - setpeerprimary could unlock a null pointer, fixed. - Added a flag in the pcb so netstat can see if we are listening easier. Obtained from: (some of the Listen changes from Weongyo Jeong)
Diffstat (limited to 'sys/netinet/sctputil.c')
-rw-r--r--sys/netinet/sctputil.c57
1 files changed, 10 insertions, 47 deletions
diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c
index 66334b4..0d0c270 100644
--- a/sys/netinet/sctputil.c
+++ b/sys/netinet/sctputil.c
@@ -3846,7 +3846,8 @@ sctp_print_address_pkt(struct ip *iph, struct sctphdr *sh)
void
sctp_pull_off_control_to_new_inp(struct sctp_inpcb *old_inp,
struct sctp_inpcb *new_inp,
- struct sctp_tcb *stcb)
+ struct sctp_tcb *stcb,
+ int waitflags)
{
/*
* go through our old INP and pull off any control structures that
@@ -3861,11 +3862,8 @@ sctp_pull_off_control_to_new_inp(struct sctp_inpcb *old_inp,
old_so = old_inp->sctp_socket;
new_so = new_inp->sctp_socket;
TAILQ_INIT(&tmp_queue);
-
SOCKBUF_LOCK(&(old_so->so_rcv));
-
- error = sblock(&old_so->so_rcv, 0);
-
+ error = sblock(&old_so->so_rcv, waitflags);
SOCKBUF_UNLOCK(&(old_so->so_rcv));
if (error) {
/*
@@ -3904,13 +3902,11 @@ sctp_pull_off_control_to_new_inp(struct sctp_inpcb *old_inp,
control = nctl;
}
SCTP_INP_READ_UNLOCK(old_inp);
-
/* Remove the sb-lock on the old socket */
SOCKBUF_LOCK(&(old_so->so_rcv));
sbunlock(&old_so->so_rcv);
SOCKBUF_UNLOCK(&(old_so->so_rcv));
-
/* Now we move them over to the new socket buffer */
control = TAILQ_FIRST(&tmp_queue);
SCTP_INP_READ_LOCK(new_inp);
@@ -4298,43 +4294,6 @@ sctp_find_ifa_in_ep(struct sctp_inpcb *inp, struct sockaddr *addr, int holds_loc
return (NULL);
}
-struct sctp_ifa *
-sctp_find_ifa_in_ifn(struct sctp_ifn *sctp_ifnp, struct sockaddr *addr,
- int holds_lock)
-{
- struct sctp_ifa *sctp_ifap;
-
- if (holds_lock == 0)
- SCTP_IPI_ADDR_LOCK();
-
- LIST_FOREACH(sctp_ifap, &sctp_ifnp->ifalist, next_ifa) {
- if (addr->sa_family != sctp_ifap->address.sa.sa_family)
- continue;
- if (addr->sa_family == AF_INET) {
- if (((struct sockaddr_in *)addr)->sin_addr.s_addr ==
- sctp_ifap->address.sin.sin_addr.s_addr) {
- /* found him. */
- if (holds_lock == 0)
- SCTP_IPI_ADDR_UNLOCK();
- return (sctp_ifap);
- break;
- }
- } else if (addr->sa_family == AF_INET6) {
- if (SCTP6_ARE_ADDR_EQUAL(&((struct sockaddr_in6 *)addr)->sin6_addr,
- &sctp_ifap->address.sin6.sin6_addr)) {
- /* found him. */
- if (holds_lock == 0)
- SCTP_IPI_ADDR_UNLOCK();
- return (sctp_ifap);
- break;
- }
- }
- }
- if (holds_lock == 0)
- SCTP_IPI_ADDR_UNLOCK();
- return (NULL);
-}
-
uint32_t
sctp_get_ifa_hash_val(struct sockaddr *addr)
{
@@ -4741,6 +4700,10 @@ restart_nosblocks:
}
goto out;
}
+ if (hold_sblock == 1) {
+ SOCKBUF_UNLOCK(&so->so_rcv);
+ hold_sblock = 0;
+ }
error = sblock(&so->so_rcv, (block_allowed ? M_WAITOK : 0));
/* we possibly have data we can read */
control = TAILQ_FIRST(&inp->read_queue);
@@ -4862,9 +4825,6 @@ found_one:
* If we reach here, control has a some data for us to read off.
* Note that stcb COULD be NULL.
*/
- if (control->do_not_ref_stcb == 0) {
- control->stcb->asoc.strmin[control->sinfo_stream].delivery_started = 1;
- }
control->some_taken = 1;
if (hold_sblock) {
SOCKBUF_UNLOCK(&so->so_rcv);
@@ -4901,6 +4861,9 @@ found_one:
stcb->freed_by_sorcv_sincelast = 0;
}
}
+ if (stcb && control->do_not_ref_stcb == 0) {
+ stcb->asoc.strmin[control->sinfo_stream].delivery_started = 1;
+ }
/* First lets get off the sinfo and sockaddr info */
if ((sinfo) && filling_sinfo) {
memcpy(sinfo, control, sizeof(struct sctp_nonpad_sndrcvinfo));
OpenPOWER on IntegriCloud