FreeBSD Bugzilla – Attachment 12405 Details for
Bug 23986
Update of "react to ICMP unreachables" code
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
file.diff
file.diff (text/plain), 6.98 KB, created by
jesper
on 2000-12-31 20:30:04 UTC
(
hide
)
Description:
file.diff
Filename:
MIME Type:
Creator:
jesper
Created:
2000-12-31 20:30:04 UTC
Size:
6.98 KB
patch
obsolete
>diff -ru sys/sys.old/protosw.h sys/sys/protosw.h >--- sys/sys.old/protosw.h Sun Dec 31 18:45:14 2000 >+++ sys/sys/protosw.h Sun Dec 31 20:05:52 2000 >@@ -275,8 +275,9 @@ > #define PRC_TIMXCEED_INTRANS 18 /* packet lifetime expired in transit */ > #define PRC_TIMXCEED_REASS 19 /* lifetime expired on reass q */ > #define PRC_PARAMPROB 20 /* header incorrect */ >+#define PRC_UNREACH_ADMIN_PROHIB 21 /* packet administrativly prohibited */ > >-#define PRC_NCMDS 21 >+#define PRC_NCMDS 22 > > #define PRC_IS_REDIRECT(cmd) \ > ((cmd) >= PRC_REDIRECT_NET && (cmd) <= PRC_REDIRECT_TOSHOST) >@@ -288,7 +289,7 @@ > "NET-UNREACH", "HOST-UNREACH", "PROTO-UNREACH", "PORT-UNREACH", > "#12", "SRCFAIL-UNREACH", "NET-REDIRECT", "HOST-REDIRECT", > "TOSNET-REDIRECT", "TOSHOST-REDIRECT", "TX-INTRANS", "TX-REASS", >- "PARAMPROB" >+ "PARAMPROB", "ADMIN-UNREACH" > }; > #endif >diff -ru sys/netinet.old/in_pcb.c sys/netinet/in_pcb.c >--- sys/netinet.old/in_pcb.c Sun Dec 31 16:07:05 2000 >+++ sys/netinet/in_pcb.c Sun Dec 31 21:10:25 2000 >@@ -732,7 +732,6 @@ > * and TCP port numbers. > */ > if ((tcp_seq_check == 1) && (tcp_seq_vs_sess(inp, tcp_sequence) == 0)) { >- inp = inp->inp_list.le_next; > break; > } > oinp = inp; >diff -ru sys/netinet.old/ip_icmp.c sys/netinet/ip_icmp.c >--- sys/netinet.old/ip_icmp.c Sun Dec 31 16:07:05 2000 >+++ sys/netinet/ip_icmp.c Sun Dec 31 19:58:31 2000 >@@ -315,11 +315,23 @@ > case ICMP_UNREACH: > switch (code) { > case ICMP_UNREACH_NET: >+ code = PRC_UNREACH_HOST; >+ break; >+ > case ICMP_UNREACH_HOST: >+ code = PRC_UNREACH_HOST; >+ break; >+ > case ICMP_UNREACH_PROTOCOL: >+ code = PRC_UNREACH_HOST; >+ break; >+ > case ICMP_UNREACH_PORT: >+ code = PRC_UNREACH_HOST; >+ break; >+ > case ICMP_UNREACH_SRCFAIL: >- code += PRC_UNREACH_NET; >+ code = PRC_UNREACH_HOST; > break; > > case ICMP_UNREACH_NEEDFRAG: >@@ -327,37 +339,43 @@ > break; > > case ICMP_UNREACH_NET_UNKNOWN: >+ code = PRC_UNREACH_HOST; >+ break; >+ > case ICMP_UNREACH_NET_PROHIB: >- if (icp->icmp_ip.ip_p == IPPROTO_TCP) { >- code = PRC_UNREACH_PORT; >- break; >- } >+ code = PRC_UNREACH_ADMIN_PROHIB; >+ break; > > case ICMP_UNREACH_TOSNET: >- code = PRC_UNREACH_NET; >+ code = PRC_UNREACH_HOST; > break; > > case ICMP_UNREACH_HOST_UNKNOWN: >+ code = PRC_UNREACH_HOST; >+ break; >+ > case ICMP_UNREACH_ISOLATED: >+ code = PRC_UNREACH_HOST; >+ break; >+ > case ICMP_UNREACH_HOST_PROHIB: >- if (icp->icmp_ip.ip_p == IPPROTO_TCP) { >- code = PRC_UNREACH_PORT; >- break; >- } >+ code = PRC_UNREACH_ADMIN_PROHIB; >+ break; > > case ICMP_UNREACH_TOSHOST: > code = PRC_UNREACH_HOST; > break; > > case ICMP_UNREACH_FILTER_PROHIB: >- if (icp->icmp_ip.ip_p == IPPROTO_TCP) { >- code = PRC_UNREACH_PORT; >- break; >- } >+ code = PRC_UNREACH_ADMIN_PROHIB; >+ break; > > case ICMP_UNREACH_HOST_PRECEDENCE: >+ code = PRC_UNREACH_HOST; >+ break; >+ > case ICMP_UNREACH_PRECEDENCE_CUTOFF: >- code = PRC_UNREACH_PORT; >+ code = PRC_UNREACH_HOST; > break; > > default: >diff -ru sys/netinet.old/tcp_subr.c sys/netinet/tcp_subr.c >--- sys/netinet.old/tcp_subr.c Sun Dec 31 16:07:04 2000 >+++ sys/netinet/tcp_subr.c Sun Dec 31 20:18:15 2000 >@@ -135,24 +135,31 @@ > &tcbinfo.ipi_count, 0, "Number of active PCBs"); > > /* >- * Treat ICMP administratively prohibited like a TCP RST >- * as required by rfc1122 section 3.2.2.1 >+ * Treat ICMP unreachables like a TCP RST as required by rfc1122 section 3.2.2.1 >+ * >+ * Administatively prohibited kill's sessions regardless of >+ * their current state, other unreachable by default only kill >+ * sessions if they are in SYN-SENT state, this ensure temporary >+ * routing problems doesn't kill existing TCP sessions. >+ * This can be overridden by icmp_like_rst_syn_sent_only. > */ > >-static int icmp_admin_prohib_like_rst = 1; >-SYSCTL_INT(_net_inet_tcp, OID_AUTO, icmp_admin_prohib_like_rst, CTLFLAG_RW, >- &icmp_admin_prohib_like_rst, 0, >- "Treat ICMP administratively prohibited messages like TCP RST, rfc1122 section 3.2.2.1"); >+static int icmp_unreach_like_rst = 1; >+SYSCTL_INT(_net_inet_tcp, OID_AUTO, icmp_unreach_like_rst, CTLFLAG_RW, >+ &icmp_unreach_like_rst, 0, >+ "Treat ICMP unreachable messages like TCP RST, rfc1122 section 3.2.2.1"); > > /* >- * When icmp_admin_prohib_like_rst is enabled, only act on >- * sessions in SYN-SENT state >+ * Control if ICMP unreachable messages other that administratively prohibited >+ * ones will kill sessions not in SYN-SENT state. >+ * >+ * Has no effect unless icmp_unreach_like_rst is enabled. > */ > > static int icmp_like_rst_syn_sent_only = 1; > SYSCTL_INT(_net_inet_tcp, OID_AUTO, icmp_like_rst_syn_sent_only, CTLFLAG_RW, > &icmp_like_rst_syn_sent_only, 0, >- "When icmp_admin_prohib_like_rst is enabled, only act on sessions in SYN-SENT state"); >+ "When icmp_unreach_like_rst is enabled, only act on sessions in SYN-SENT state"); > > static void tcp_cleartaocache __P((void)); > static void tcp_notify __P((struct inpcb *, int)); >@@ -983,17 +990,27 @@ > > if (cmd == PRC_QUENCH) > notify = tcp_quench; >- else if ((icmp_admin_prohib_like_rst == 1) && (cmd == PRC_UNREACH_PORT) && >- (ip) && ((IP_VHL_HL(ip->ip_vhl) << 2) == sizeof(struct ip))) { >+ else if ((icmp_unreach_like_rst == 1) && ((cmd == PRC_UNREACH_HOST) || >+ (cmd == PRC_UNREACH_ADMIN_PROHIB)) && (ip) && >+ ((IP_VHL_HL(ip->ip_vhl) << 2) == sizeof(struct ip))) { > /* > * Only go here if the length of the IP header in the ICMP packet > * is 20 bytes, that is it doesn't have options, if it does have > * options, we will not have the first 8 bytes of the TCP header, > * and thus we cannot match against TCP source/destination port > * numbers and TCP sequence number. >+ * >+ * If PRC_UNREACH_ADMIN_PROHIB drop session regardsless of current >+ * state, else we check the sysctl icmp_like_rst_syn_sent_only to >+ * see if we should drop the session only in SYN-SENT state, or >+ * in all states. > */ > tcp_seq_check = 1; >- notify = tcp_drop_syn_sent; >+ if (cmd == PRC_UNREACH_ADMIN_PROHIB) { >+ notify = tcp_drop_all_states; >+ } else { >+ notify = tcp_drop_syn_sent; >+ } > } else if (cmd == PRC_MSGSIZE) > notify = tcp_mtudisc; > else if (!PRC_IS_REDIRECT(cmd) && >@@ -1146,6 +1163,20 @@ > struct tcpcb *tp = intotcpcb(inp); > if((tp) && ((icmp_like_rst_syn_sent_only == 0) || > (tp->t_state == TCPS_SYN_SENT))) >+ tcp_drop(tp, errno); >+} >+ >+/* >+ * When a ICMP unreachable is recieved, drop the >+ * TCP connection, regardless of the state. >+ */ >+void >+tcp_drop_all_states(inp, errno) >+ struct inpcb *inp; >+ int errno; >+{ >+ struct tcpcb *tp = intotcpcb(inp); >+ if(tp) > tcp_drop(tp, errno); > } > >diff -ru sys/netinet.old/tcp_var.h sys/netinet/tcp_var.h >--- sys/netinet.old/tcp_var.h Sun Dec 31 16:07:04 2000 >+++ sys/netinet/tcp_var.h Sun Dec 31 20:30:12 2000 >@@ -388,6 +388,7 @@ > void tcp_mss __P((struct tcpcb *, int)); > int tcp_mssopt __P((struct tcpcb *)); > void tcp_drop_syn_sent __P((struct inpcb *, int)); >+void tcp_drop_all_states __P((struct inpcb *, int)); > void tcp_mtudisc __P((struct inpcb *, int)); > struct tcpcb * > tcp_newtcpcb __P((struct inpcb *));
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 23986
: 12405