summaryrefslogtreecommitdiffstats
path: root/sys/netinet
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2006-06-03 19:37:08 +0000
committerrwatson <rwatson@FreeBSD.org>2006-06-03 19:37:08 +0000
commit8d3568ae0be8d4f8b0f415366e93bfc52de32dbe (patch)
treeff22778b3a233a1cacac21148c53f4ba9015179e /sys/netinet
parent133fd236d101c0bcc7a0d460848ed4ea4c15a47b (diff)
downloadFreeBSD-src-8d3568ae0be8d4f8b0f415366e93bfc52de32dbe.zip
FreeBSD-src-8d3568ae0be8d4f8b0f415366e93bfc52de32dbe.tar.gz
When entering a timer on a tcpcb, don't continue processing if it has been
dropped. This prevents a bug introduced during the socket/pcb refcounting work from occuring, in which occasionally the retransmit timer may fire after a connection has been reset, resulting in the resulting R|A TCP packet having a source port of 0, as the port reservation has been released. While here, fixing up some RUNLOCK->WUNLOCK bugs. MFC after: 1 month
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/tcp_timer.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/sys/netinet/tcp_timer.c b/sys/netinet/tcp_timer.c
index 6dfc8df..6b8698c 100644
--- a/sys/netinet/tcp_timer.c
+++ b/sys/netinet/tcp_timer.c
@@ -156,7 +156,8 @@ tcp_timer_delack(xtp)
}
INP_LOCK(inp);
INP_INFO_RUNLOCK(&tcbinfo);
- if (callout_pending(tp->tt_delack) || !callout_active(tp->tt_delack)) {
+ if ((inp->inp_vflag & INP_DROPPED) || callout_pending(tp->tt_delack)
+ || !callout_active(tp->tt_delack)) {
INP_UNLOCK(inp);
return;
}
@@ -193,12 +194,13 @@ tcp_timer_2msl(xtp)
*/
if (inp == NULL) {
tcp_timer_race++;
- INP_INFO_RUNLOCK(&tcbinfo);
+ INP_INFO_WUNLOCK(&tcbinfo);
return;
}
INP_LOCK(inp);
tcp_free_sackholes(tp);
- if (callout_pending(tp->tt_2msl) || !callout_active(tp->tt_2msl)) {
+ if ((inp->inp_vflag & INP_DROPPED) || callout_pending(tp->tt_2msl) ||
+ !callout_active(tp->tt_2msl)) {
INP_UNLOCK(tp->t_inpcb);
INP_INFO_WUNLOCK(&tcbinfo);
return;
@@ -323,11 +325,12 @@ tcp_timer_keep(xtp)
*/
if (inp == NULL) {
tcp_timer_race++;
- INP_INFO_RUNLOCK(&tcbinfo);
+ INP_INFO_WUNLOCK(&tcbinfo);
return;
}
INP_LOCK(inp);
- if (callout_pending(tp->tt_keep) || !callout_active(tp->tt_keep)) {
+ if ((inp->inp_vflag & INP_DROPPED) || callout_pending(tp->tt_keep)
+ || !callout_active(tp->tt_keep)) {
INP_UNLOCK(inp);
INP_INFO_WUNLOCK(&tcbinfo);
return;
@@ -413,11 +416,12 @@ tcp_timer_persist(xtp)
*/
if (inp == NULL) {
tcp_timer_race++;
- INP_INFO_RUNLOCK(&tcbinfo);
+ INP_INFO_WUNLOCK(&tcbinfo);
return;
}
INP_LOCK(inp);
- if (callout_pending(tp->tt_persist) || !callout_active(tp->tt_persist)){
+ if ((inp->inp_vflag & INP_DROPPED) || callout_pending(tp->tt_persist)
+ || !callout_active(tp->tt_persist)) {
INP_UNLOCK(inp);
INP_INFO_WUNLOCK(&tcbinfo);
return;
@@ -482,11 +486,12 @@ tcp_timer_rexmt(xtp)
*/
if (inp == NULL) {
tcp_timer_race++;
- INP_INFO_RUNLOCK(&tcbinfo);
+ INP_INFO_WUNLOCK(&tcbinfo);
return;
}
INP_LOCK(inp);
- if (callout_pending(tp->tt_rexmt) || !callout_active(tp->tt_rexmt)) {
+ if ((inp->inp_vflag & INP_DROPPED) || callout_pending(tp->tt_rexmt)
+ || !callout_active(tp->tt_rexmt)) {
INP_UNLOCK(inp);
INP_INFO_WUNLOCK(&tcbinfo);
return;
OpenPOWER on IntegriCloud