diff options
author | rrs <rrs@FreeBSD.org> | 2007-05-02 12:50:13 +0000 |
---|---|---|
committer | rrs <rrs@FreeBSD.org> | 2007-05-02 12:50:13 +0000 |
commit | 803b9be8be0827d6f2fde839f6dcd9225a2609be (patch) | |
tree | 93ea4f957056813b10463b788259dc0304a365e3 /sys/netinet/sctputil.c | |
parent | 78898ea5a86dc4f5a06f63d1f2c50c2c6497bef9 (diff) | |
download | FreeBSD-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.c | 57 |
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)); |