Skip to content

Commit eddb43a

Browse files
committed
Handle sockets that are closing in parallel.
After unlocking, sockets may close on one CPU while others are processing packets. For TCP the socket lock prevents this. Add a netstat counter for dropped packets if an inpcb has no associated socket after the lock has been acquired. UDP, raw IP, and divert sockets rely only on reference count. They do not take socket lock as they have little state to protect and want to avoid the performance penalty. This means that inp->inp_socket->so_pcb can become NULL anytime. Remove a kassert that checks this value. All other parts of the socket are either read only or protected by mutex. Sockets may still receive data into socket buffer while the socket is closing. After releasing all references, sorele() calls m_purge() and has to deal with it. OK mvs@
1 parent bce3dfd commit eddb43a

File tree

4 files changed

+8
-7
lines changed

4 files changed

+8
-7
lines changed

sys/netinet/tcp_input.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $OpenBSD: tcp_input.c,v 1.452 2025/06/12 19:10:17 bluhm Exp $ */
1+
/* $OpenBSD: tcp_input.c,v 1.453 2025/06/18 16:15:46 bluhm Exp $ */
22
/* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */
33

44
/*
@@ -661,10 +661,9 @@ tcp_input_solocked(struct mbuf **mp, int *offp, int proto, int af,
661661
so = in_pcbsolock(inp);
662662
}
663663
if (so == NULL) {
664-
tcpstat_inc(tcps_noport);
664+
tcpstat_inc(tcps_closing);
665665
goto dropwithreset_ratelim;
666666
}
667-
668667
KASSERT(sotoinpcb(inp->inp_socket) == inp);
669668
KASSERT(intotcpcb(inp) == NULL || intotcpcb(inp)->t_inpcb == inp);
670669
soassertlocked(inp->inp_socket);

sys/netinet/tcp_var.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $OpenBSD: tcp_var.h,v 1.194 2025/06/17 03:48:14 dlg Exp $ */
1+
/* $OpenBSD: tcp_var.h,v 1.195 2025/06/18 16:15:46 bluhm Exp $ */
22
/* $NetBSD: tcp_var.h,v 1.17 1996/02/13 23:44:24 christos Exp $ */
33

44
/*
@@ -392,6 +392,7 @@ struct tcpstat {
392392

393393
u_int32_t tcps_pcbhashmiss; /* input packets missing pcb hash */
394394
u_int32_t tcps_noport; /* no socket on port */
395+
u_int32_t tcps_closing; /* inpcb exists, socket is closing */
395396
u_int32_t tcps_badsyn; /* SYN packet with src==dst rcv'ed */
396397
u_int32_t tcps_dropsyn; /* SYN packet dropped */
397398

@@ -582,6 +583,7 @@ enum tcpstat_counters {
582583
tcps_preddat,
583584
tcps_pcbhashmiss,
584585
tcps_noport,
586+
tcps_closing,
585587
tcps_badsyn,
586588
tcps_dropsyn,
587589
tcps_rcvbadsig,

sys/netinet/udp_usrreq.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $OpenBSD: udp_usrreq.c,v 1.343 2025/06/16 07:11:58 mvs Exp $ */
1+
/* $OpenBSD: udp_usrreq.c,v 1.344 2025/06/18 16:15:46 bluhm Exp $ */
22
/* $NetBSD: udp_usrreq.c,v 1.28 1996/03/16 23:54:03 christos Exp $ */
33

44
/*
@@ -602,7 +602,6 @@ udp_input(struct mbuf **mp, int *offp, int proto, int af, struct netstack *ns)
602602
return IPPROTO_DONE;
603603
}
604604

605-
KASSERT(sotoinpcb(inp->inp_socket) == inp);
606605
soassertlocked_readonly(inp->inp_socket);
607606

608607
#ifdef INET6

usr.bin/netstat/inet.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $OpenBSD: inet.c,v 1.184 2025/04/17 17:23:17 bluhm Exp $ */
1+
/* $OpenBSD: inet.c,v 1.185 2025/06/18 16:15:46 bluhm Exp $ */
22
/* $NetBSD: inet.c,v 1.14 1995/10/03 21:42:37 thorpej Exp $ */
33

44
/*
@@ -468,6 +468,7 @@ tcp_stats(char *name)
468468
p(tcps_preddat, "\t%u correct data packet header prediction%s\n");
469469
pes(tcps_pcbhashmiss, "\t%u PCB cache miss%s\n");
470470
p1(tcps_noport, "\t%u dropped due to no socket\n");
471+
p1(tcps_closing, "\t%u dropped as socket is closing\n");
471472

472473
p(tcps_ecn_accepts, "\t%u ECN connection%s accepted\n");
473474
p(tcps_ecn_rcvece, "\t\t%u ECE packet%s received\n");

0 commit comments

Comments
 (0)