View | Details | Raw Unified | Return to bug 23986
Collapse All | Expand All

(-)sys/sys/protosw.h (-2 / +3 lines)
Lines 275-282 Link Here
275
#define	PRC_TIMXCEED_INTRANS	18	/* packet lifetime expired in transit */
275
#define	PRC_TIMXCEED_INTRANS	18	/* packet lifetime expired in transit */
276
#define	PRC_TIMXCEED_REASS	19	/* lifetime expired on reass q */
276
#define	PRC_TIMXCEED_REASS	19	/* lifetime expired on reass q */
277
#define	PRC_PARAMPROB		20	/* header incorrect */
277
#define	PRC_PARAMPROB		20	/* header incorrect */
278
#define	PRC_UNREACH_ADMIN_PROHIB	21	/* packet administrativly prohibited */
278
279
279
#define	PRC_NCMDS		21
280
#define	PRC_NCMDS		22
280
281
281
#define	PRC_IS_REDIRECT(cmd)	\
282
#define	PRC_IS_REDIRECT(cmd)	\
282
	((cmd) >= PRC_REDIRECT_NET && (cmd) <= PRC_REDIRECT_TOSHOST)
283
	((cmd) >= PRC_REDIRECT_NET && (cmd) <= PRC_REDIRECT_TOSHOST)
Lines 288-294 Link Here
288
	"NET-UNREACH", "HOST-UNREACH", "PROTO-UNREACH", "PORT-UNREACH",
289
	"NET-UNREACH", "HOST-UNREACH", "PROTO-UNREACH", "PORT-UNREACH",
289
	"#12", "SRCFAIL-UNREACH", "NET-REDIRECT", "HOST-REDIRECT",
290
	"#12", "SRCFAIL-UNREACH", "NET-REDIRECT", "HOST-REDIRECT",
290
	"TOSNET-REDIRECT", "TOSHOST-REDIRECT", "TX-INTRANS", "TX-REASS",
291
	"TOSNET-REDIRECT", "TOSHOST-REDIRECT", "TX-INTRANS", "TX-REASS",
291
	"PARAMPROB"
292
	"PARAMPROB", "ADMIN-UNREACH"
292
};
293
};
293
#endif
294
#endif
(-)sys/netinet/in_pcb.c (-1 lines)
Lines 732-738 Link Here
732
		 * and TCP port numbers.
732
		 * and TCP port numbers.
733
		 */
733
		 */
734
		if ((tcp_seq_check == 1) && (tcp_seq_vs_sess(inp, tcp_sequence) == 0)) {
734
		if ((tcp_seq_check == 1) && (tcp_seq_vs_sess(inp, tcp_sequence) == 0)) {
735
			inp = inp->inp_list.le_next;
736
			break;
735
			break;
737
		}
736
		}
738
		oinp = inp;
737
		oinp = inp;
(-)sys/netinet/ip_icmp.c (-15 / +33 lines)
Lines 315-325 Link Here
315
	case ICMP_UNREACH:
315
	case ICMP_UNREACH:
316
		switch (code) {
316
		switch (code) {
317
			case ICMP_UNREACH_NET:
317
			case ICMP_UNREACH_NET:
318
				code = PRC_UNREACH_HOST;
319
				break;
320
318
			case ICMP_UNREACH_HOST:
321
			case ICMP_UNREACH_HOST:
322
				code = PRC_UNREACH_HOST;
323
				break;
324
319
			case ICMP_UNREACH_PROTOCOL:
325
			case ICMP_UNREACH_PROTOCOL:
326
				code = PRC_UNREACH_HOST;
327
				break;
328
320
			case ICMP_UNREACH_PORT:
329
			case ICMP_UNREACH_PORT:
330
				code = PRC_UNREACH_HOST;
331
				break;
332
321
			case ICMP_UNREACH_SRCFAIL:
333
			case ICMP_UNREACH_SRCFAIL:
322
				code += PRC_UNREACH_NET;
334
				code = PRC_UNREACH_HOST;
323
				break;
335
				break;
324
336
325
			case ICMP_UNREACH_NEEDFRAG:
337
			case ICMP_UNREACH_NEEDFRAG:
Lines 327-363 Link Here
327
				break;
339
				break;
328
340
329
			case ICMP_UNREACH_NET_UNKNOWN:
341
			case ICMP_UNREACH_NET_UNKNOWN:
342
				code = PRC_UNREACH_HOST;
343
				break;
344
330
			case ICMP_UNREACH_NET_PROHIB:
345
			case ICMP_UNREACH_NET_PROHIB:
331
				if (icp->icmp_ip.ip_p == IPPROTO_TCP) {
346
				code = PRC_UNREACH_ADMIN_PROHIB;
332
					code = PRC_UNREACH_PORT;
347
				break;
333
					break;
334
				}
335
348
336
			case ICMP_UNREACH_TOSNET:
349
			case ICMP_UNREACH_TOSNET:
337
				code = PRC_UNREACH_NET;
350
				code = PRC_UNREACH_HOST;
338
				break;
351
				break;
339
352
340
			case ICMP_UNREACH_HOST_UNKNOWN:
353
			case ICMP_UNREACH_HOST_UNKNOWN:
354
				code = PRC_UNREACH_HOST;
355
				break;
356
341
			case ICMP_UNREACH_ISOLATED:
357
			case ICMP_UNREACH_ISOLATED:
358
				code = PRC_UNREACH_HOST;
359
				break;
360
342
			case ICMP_UNREACH_HOST_PROHIB:
361
			case ICMP_UNREACH_HOST_PROHIB:
343
				if (icp->icmp_ip.ip_p == IPPROTO_TCP) {
362
				code = PRC_UNREACH_ADMIN_PROHIB;
344
					code = PRC_UNREACH_PORT;
363
				break;
345
					break;
346
				}
347
364
348
			case ICMP_UNREACH_TOSHOST:
365
			case ICMP_UNREACH_TOSHOST:
349
				code = PRC_UNREACH_HOST;
366
				code = PRC_UNREACH_HOST;
350
				break;
367
				break;
351
368
352
			case ICMP_UNREACH_FILTER_PROHIB:
369
			case ICMP_UNREACH_FILTER_PROHIB:
353
				if (icp->icmp_ip.ip_p == IPPROTO_TCP) {
370
				code = PRC_UNREACH_ADMIN_PROHIB;
354
					code = PRC_UNREACH_PORT;
371
				break;
355
					break;
356
				}
357
372
358
			case ICMP_UNREACH_HOST_PRECEDENCE:
373
			case ICMP_UNREACH_HOST_PRECEDENCE:
374
				code = PRC_UNREACH_HOST;
375
				break;
376
359
			case ICMP_UNREACH_PRECEDENCE_CUTOFF:
377
			case ICMP_UNREACH_PRECEDENCE_CUTOFF:
360
				code = PRC_UNREACH_PORT;
378
				code = PRC_UNREACH_HOST;
361
				break;
379
				break;
362
380
363
			default:
381
			default:
(-)sys/netinet/tcp_subr.c (-12 / +43 lines)
Lines 135-158 Link Here
135
    &tcbinfo.ipi_count, 0, "Number of active PCBs");
135
    &tcbinfo.ipi_count, 0, "Number of active PCBs");
136
136
137
/*
137
/*
138
 * Treat ICMP administratively prohibited like a TCP RST
138
 * Treat ICMP unreachables like a TCP RST as required by rfc1122 section 3.2.2.1
139
 * as required by rfc1122 section 3.2.2.1
139
 *
140
 * Administatively prohibited kill's sessions regardless of
141
 * their current state, other unreachable by default only kill 
142
 * sessions if they are in SYN-SENT state, this ensure temporary 
143
 * routing problems doesn't kill existing TCP sessions.
144
 * This can be overridden by icmp_like_rst_syn_sent_only.
140
 */
145
 */
141
 
146
 
142
static int	icmp_admin_prohib_like_rst = 1;
147
static int	icmp_unreach_like_rst = 1;
143
SYSCTL_INT(_net_inet_tcp, OID_AUTO, icmp_admin_prohib_like_rst, CTLFLAG_RW,
148
SYSCTL_INT(_net_inet_tcp, OID_AUTO, icmp_unreach_like_rst, CTLFLAG_RW,
144
	&icmp_admin_prohib_like_rst, 0, 
149
	&icmp_unreach_like_rst, 0, 
145
	"Treat ICMP administratively prohibited messages like TCP RST, rfc1122 section 3.2.2.1");
150
	"Treat ICMP unreachable messages like TCP RST, rfc1122 section 3.2.2.1");
146
151
147
/*
152
/*
148
 * When icmp_admin_prohib_like_rst is enabled, only act on
153
 * Control if ICMP unreachable messages other that administratively prohibited
149
 * sessions in SYN-SENT state
154
 * ones will kill sessions not in SYN-SENT state.
155
 *
156
 * Has no effect unless icmp_unreach_like_rst is enabled.
150
 */
157
 */
151
158
152
static int	icmp_like_rst_syn_sent_only = 1;
159
static int	icmp_like_rst_syn_sent_only = 1;
153
SYSCTL_INT(_net_inet_tcp, OID_AUTO, icmp_like_rst_syn_sent_only, CTLFLAG_RW,
160
SYSCTL_INT(_net_inet_tcp, OID_AUTO, icmp_like_rst_syn_sent_only, CTLFLAG_RW,
154
	&icmp_like_rst_syn_sent_only, 0, 
161
	&icmp_like_rst_syn_sent_only, 0, 
155
	"When icmp_admin_prohib_like_rst is enabled, only act on sessions in SYN-SENT state");
162
	"When icmp_unreach_like_rst is enabled, only act on sessions in SYN-SENT state");
156
163
157
static void	tcp_cleartaocache __P((void));
164
static void	tcp_cleartaocache __P((void));
158
static void	tcp_notify __P((struct inpcb *, int));
165
static void	tcp_notify __P((struct inpcb *, int));
Lines 983-999 Link Here
983
990
984
	if (cmd == PRC_QUENCH)
991
	if (cmd == PRC_QUENCH)
985
		notify = tcp_quench;
992
		notify = tcp_quench;
986
	else if ((icmp_admin_prohib_like_rst == 1) && (cmd == PRC_UNREACH_PORT) && 
993
	else if ((icmp_unreach_like_rst == 1) && ((cmd == PRC_UNREACH_HOST) ||
987
			(ip) && ((IP_VHL_HL(ip->ip_vhl) << 2) == sizeof(struct ip))) {
994
			(cmd == PRC_UNREACH_ADMIN_PROHIB)) && (ip) && 
995
			((IP_VHL_HL(ip->ip_vhl) << 2) == sizeof(struct ip))) {
988
		/*
996
		/*
989
		 * Only go here if the length of the IP header in the ICMP packet
997
		 * Only go here if the length of the IP header in the ICMP packet
990
		 * is 20 bytes, that is it doesn't have options, if it does have
998
		 * is 20 bytes, that is it doesn't have options, if it does have
991
		 * options, we will not have the first 8 bytes of the TCP header,
999
		 * options, we will not have the first 8 bytes of the TCP header,
992
		 * and thus we cannot match against TCP source/destination port
1000
		 * and thus we cannot match against TCP source/destination port
993
		 * numbers and TCP sequence number.
1001
		 * numbers and TCP sequence number.
1002
		 *
1003
		 * If PRC_UNREACH_ADMIN_PROHIB drop session regardsless of current
1004
		 * state, else we check the sysctl icmp_like_rst_syn_sent_only to
1005
		 * see if we should drop the session only in SYN-SENT state, or
1006
		 * in all states.
994
		 */
1007
		 */
995
		tcp_seq_check = 1;
1008
		tcp_seq_check = 1;
996
		notify = tcp_drop_syn_sent;
1009
		if (cmd == PRC_UNREACH_ADMIN_PROHIB) {
1010
			notify = tcp_drop_all_states;
1011
		} else {
1012
			notify = tcp_drop_syn_sent;
1013
		}
997
	} else if (cmd == PRC_MSGSIZE)
1014
	} else if (cmd == PRC_MSGSIZE)
998
		notify = tcp_mtudisc;
1015
		notify = tcp_mtudisc;
999
	else if (!PRC_IS_REDIRECT(cmd) &&
1016
	else if (!PRC_IS_REDIRECT(cmd) &&
Lines 1146-1151 Link Here
1146
	struct tcpcb *tp = intotcpcb(inp);
1163
	struct tcpcb *tp = intotcpcb(inp);
1147
	if((tp) && ((icmp_like_rst_syn_sent_only == 0) || 
1164
	if((tp) && ((icmp_like_rst_syn_sent_only == 0) || 
1148
			(tp->t_state == TCPS_SYN_SENT)))
1165
			(tp->t_state == TCPS_SYN_SENT)))
1166
		tcp_drop(tp, errno);
1167
}
1168
1169
/*
1170
 * When a ICMP unreachable is recieved, drop the
1171
 * TCP connection, regardless of the state.
1172
 */
1173
void
1174
tcp_drop_all_states(inp, errno)
1175
	struct inpcb *inp;
1176
	int errno;
1177
{
1178
	struct tcpcb *tp = intotcpcb(inp);
1179
	if(tp)
1149
		tcp_drop(tp, errno);
1180
		tcp_drop(tp, errno);
1150
}
1181
}
1151
1182
(-)sys/netinet/tcp_var.h (+1 lines)
Lines 388-393 Link Here
388
void	 tcp_mss __P((struct tcpcb *, int));
388
void	 tcp_mss __P((struct tcpcb *, int));
389
int	 tcp_mssopt __P((struct tcpcb *));
389
int	 tcp_mssopt __P((struct tcpcb *));
390
void	 tcp_drop_syn_sent __P((struct inpcb *, int));
390
void	 tcp_drop_syn_sent __P((struct inpcb *, int));
391
void	 tcp_drop_all_states __P((struct inpcb *, int));
391
void	 tcp_mtudisc __P((struct inpcb *, int));
392
void	 tcp_mtudisc __P((struct inpcb *, int));
392
struct tcpcb *
393
struct tcpcb *
393
	 tcp_newtcpcb __P((struct inpcb *));
394
	 tcp_newtcpcb __P((struct inpcb *));

Return to bug 23986