summaryrefslogtreecommitdiff
path: root/sys/netinet/in_pcb.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet/in_pcb.c')
-rw-r--r--sys/netinet/in_pcb.c68
1 files changed, 45 insertions, 23 deletions
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index c114ecae48bb..0a8e95238cd1 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -78,8 +78,6 @@
struct in_addr zeroin_addr;
-static void in_rtchange __P((struct inpcb *, int));
-
/*
* These configure the range of local port addresses assigned to
* "unspecified" outgoing connections/packets/whatever.
@@ -693,20 +691,6 @@ in_pcbnotify(head, dst, fport_arg, laddr, lport_arg, cmd, notify, tcp_sequence,
if (faddr.s_addr == INADDR_ANY)
return;
- /*
- * Redirects go to all references to the destination,
- * and use in_rtchange to invalidate the route cache.
- * Dead host indications: notify all references to the destination.
- * Otherwise, if we have knowledge of the local port and address,
- * deliver only to that socket.
- */
- if (PRC_IS_REDIRECT(cmd) || cmd == PRC_HOSTDEAD) {
- fport = 0;
- lport = 0;
- laddr.s_addr = 0;
- if (cmd != PRC_HOSTDEAD)
- notify = in_rtchange;
- }
errno = inetctlerrmap[cmd];
s = splnet();
for (inp = LIST_FIRST(head); inp != NULL;) {
@@ -717,12 +701,11 @@ in_pcbnotify(head, dst, fport_arg, laddr, lport_arg, cmd, notify, tcp_sequence,
}
#endif
if (inp->inp_faddr.s_addr != faddr.s_addr ||
- inp->inp_socket == 0 ||
- (lport && inp->inp_lport != lport) ||
- (laddr.s_addr && inp->inp_laddr.s_addr != laddr.s_addr) ||
- (fport && inp->inp_fport != fport)) {
- inp = LIST_NEXT(inp, inp_list);
- continue;
+ inp->inp_socket == 0 || inp->inp_lport != lport ||
+ inp->inp_laddr.s_addr != laddr.s_addr ||
+ inp->inp_fport != fport) {
+ inp = LIST_NEXT(inp, inp_list);
+ continue;
}
/*
* If tcp_seq_check is set, then skip sessions where
@@ -743,6 +726,45 @@ in_pcbnotify(head, dst, fport_arg, laddr, lport_arg, cmd, notify, tcp_sequence,
splx(s);
}
+void
+in_pcbnotifyall(head, dst, cmd, notify)
+ struct inpcbhead *head;
+ struct sockaddr *dst;
+ int cmd;
+ void (*notify) __P((struct inpcb *, int));
+{
+ register struct inpcb *inp, *oinp;
+ struct in_addr faddr;
+ int errno, s;
+
+ if ((unsigned)cmd > PRC_NCMDS || dst->sa_family != AF_INET)
+ return;
+ faddr = ((struct sockaddr_in *)dst)->sin_addr;
+ if (faddr.s_addr == INADDR_ANY)
+ return;
+
+ errno = inetctlerrmap[cmd];
+ s = splnet();
+ for (inp = LIST_FIRST(head); inp != NULL;) {
+#ifdef INET6
+ if ((inp->inp_vflag & INP_IPV4) == 0) {
+ inp = LIST_NEXT(inp, inp_list);
+ continue;
+ }
+#endif
+ if (inp->inp_faddr.s_addr != faddr.s_addr ||
+ inp->inp_socket == 0) {
+ inp = LIST_NEXT(inp, inp_list);
+ continue;
+ }
+ oinp = inp;
+ inp = LIST_NEXT(inp, inp_list);
+ if (notify)
+ (*notify)(oinp, errno);
+ }
+ splx(s);
+}
+
/*
* Check for alternatives when higher level complains
* about service problems. For now, invalidate cached
@@ -781,7 +803,7 @@ in_losing(inp)
* After a routing change, flush old routing
* and allocate a (hopefully) better one.
*/
-static void
+void
in_rtchange(inp, errno)
register struct inpcb *inp;
int errno;