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

(-)sys/netinet/in_pcb.c (-1 / +11 lines)
Lines 667-679 Link Here
667
 * any errors for each matching socket.
667
 * any errors for each matching socket.
668
 */
668
 */
669
void
669
void
670
in_pcbnotify(head, dst, fport_arg, laddr, lport_arg, cmd, notify)
670
in_pcbnotify(head, dst, fport_arg, laddr, lport_arg, cmd, notify, tcp_sequence)
671
	struct inpcbhead *head;
671
	struct inpcbhead *head;
672
	struct sockaddr *dst;
672
	struct sockaddr *dst;
673
	u_int fport_arg, lport_arg;
673
	u_int fport_arg, lport_arg;
674
	struct in_addr laddr;
674
	struct in_addr laddr;
675
	int cmd;
675
	int cmd;
676
	void (*notify) __P((struct inpcb *, int));
676
	void (*notify) __P((struct inpcb *, int));
677
	u_int32_t tcp_sequence;
677
{
678
{
678
	register struct inpcb *inp, *oinp;
679
	register struct inpcb *inp, *oinp;
679
	struct in_addr faddr;
680
	struct in_addr faddr;
Lines 714-719 Link Here
714
		    (lport && inp->inp_lport != lport) ||
715
		    (lport && inp->inp_lport != lport) ||
715
		    (laddr.s_addr && inp->inp_laddr.s_addr != laddr.s_addr) ||
716
		    (laddr.s_addr && inp->inp_laddr.s_addr != laddr.s_addr) ||
716
		    (fport && inp->inp_fport != fport)) {
717
		    (fport && inp->inp_fport != fport)) {
718
			inp = inp->inp_list.le_next;
719
			continue;
720
		}
721
		/*
722
		 * If tcp_sequence is set, then skip sessions where
723
		 * the sequence number is not one of a unacknowledged
724
		 * packet.
725
		 */
726
		if ((tcp_sequence) && (tcp_seq_vs_sess(inp, tcp_sequence) == 0)) {
717
			inp = inp->inp_list.le_next;
727
			inp = inp->inp_list.le_next;
718
			continue;
728
			continue;
719
		}
729
		}
(-)sys/netinet/in_pcb.h (-1 / +1 lines)
Lines 290-296 Link Here
290
			       struct in_addr, u_int, struct in_addr, u_int,
290
			       struct in_addr, u_int, struct in_addr, u_int,
291
			       int, struct ifnet *));
291
			       int, struct ifnet *));
292
void	in_pcbnotify __P((struct inpcbhead *, struct sockaddr *,
292
void	in_pcbnotify __P((struct inpcbhead *, struct sockaddr *,
293
	    u_int, struct in_addr, u_int, int, void (*)(struct inpcb *, int)));
293
	    u_int, struct in_addr, u_int, int, void (*)(struct inpcb *, int), u_int32_t));
294
void	in_pcbrehash __P((struct inpcb *));
294
void	in_pcbrehash __P((struct inpcb *));
295
int	in_setpeeraddr __P((struct socket *so, struct sockaddr **nam));
295
int	in_setpeeraddr __P((struct socket *so, struct sockaddr **nam));
296
int	in_setsockaddr __P((struct socket *so, struct sockaddr **nam));
296
int	in_setsockaddr __P((struct socket *so, struct sockaddr **nam));
(-)sys/netinet/tcp_subr.c (-8 / +57 lines)
Lines 139-147 Link Here
139
 * as required by rfc1122 section 3.2.2.1
139
 * as required by rfc1122 section 3.2.2.1
140
 */
140
 */
141
 
141
 
142
static int	icmp_admin_prohib_like_rst = 0;
142
static int	icmp_admin_prohib_like_rst = 1;
143
SYSCTL_INT(_net_inet_tcp, OID_AUTO, icmp_admin_prohib_like_rst, CTLFLAG_RW,
143
SYSCTL_INT(_net_inet_tcp, OID_AUTO, icmp_admin_prohib_like_rst, CTLFLAG_RW,
144
	&icmp_admin_prohib_like_rst, 0, "Treat ICMP administratively prohibited messages like TCP RST, rfc1122 section 3.2.2.1");
144
	&icmp_admin_prohib_like_rst, 0, 
145
	"Treat ICMP administratively prohibited messages like TCP RST, rfc1122 section 3.2.2.1");
146
147
/*
148
 * When icmp_admin_prohib_like_rst is enabled, only act on
149
 * sessions in SYN-SENT state
150
 */
151
152
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,
154
	&icmp_like_rst_syn_sent_only, 0, 
155
	"When icmp_admin_prohib_like_rst is enabled, only act on sessions in SYN-SENT state");
145
156
146
static void	tcp_cleartaocache __P((void));
157
static void	tcp_cleartaocache __P((void));
147
static void	tcp_notify __P((struct inpcb *, int));
158
static void	tcp_notify __P((struct inpcb *, int));
Lines 967-976 Link Here
967
	register struct ip *ip = vip;
978
	register struct ip *ip = vip;
968
	register struct tcphdr *th;
979
	register struct tcphdr *th;
969
	void (*notify) __P((struct inpcb *, int)) = tcp_notify;
980
	void (*notify) __P((struct inpcb *, int)) = tcp_notify;
981
	tcp_seq tcp_sequence = 0;
970
982
971
	if (cmd == PRC_QUENCH)
983
	if (cmd == PRC_QUENCH)
972
		notify = tcp_quench;
984
		notify = tcp_quench;
973
	else if ((icmp_admin_prohib_like_rst == 1) && (cmd == PRC_UNREACH_PORT) && (ip))
985
	else if ((icmp_admin_prohib_like_rst == 1) && (cmd == PRC_UNREACH_PORT) && 
986
			(ip) && ((IP_VHL_HL(ip->ip_vhl) << 2) == sizeof(struct ip)))
987
		/*
988
		 * Only go here if the length of the IP header in the ICMP packet
989
		 * is 20 bytes, that is it doesn't have options, if it does have
990
		 * options, we will not have the first 8 bytes of the TCP header,
991
		 * and thus we cannot match against TCP source/destination port
992
		 * numbers and TCP sequence number.
993
		 */
974
		notify = tcp_drop_syn_sent;
994
		notify = tcp_drop_syn_sent;
975
	else if (cmd == PRC_MSGSIZE)
995
	else if (cmd == PRC_MSGSIZE)
976
		notify = tcp_mtudisc;
996
		notify = tcp_mtudisc;
Lines 980-989 Link Here
980
	if (ip) {
1000
	if (ip) {
981
		th = (struct tcphdr *)((caddr_t)ip 
1001
		th = (struct tcphdr *)((caddr_t)ip 
982
				       + (IP_VHL_HL(ip->ip_vhl) << 2));
1002
				       + (IP_VHL_HL(ip->ip_vhl) << 2));
1003
		if (notify == tcp_drop_syn_sent)
1004
			tcp_sequence = ntohl(th->th_seq);
983
		in_pcbnotify(&tcb, sa, th->th_dport, ip->ip_src, th->th_sport,
1005
		in_pcbnotify(&tcb, sa, th->th_dport, ip->ip_src, th->th_sport,
984
			cmd, notify);
1006
			cmd, notify, tcp_sequence);
985
	} else
1007
	} else
986
		in_pcbnotify(&tcb, sa, 0, zeroin_addr, 0, cmd, notify);
1008
		in_pcbnotify(&tcb, sa, 0, zeroin_addr, 0, cmd, notify, 0);
987
}
1009
}
988
1010
989
#ifdef INET6
1011
#ifdef INET6
Lines 1070-1075 Link Here
1070
#endif /* INET6 */
1092
#endif /* INET6 */
1071
1093
1072
/*
1094
/*
1095
 * Check if the supplied TCP sequence number is a sequence number
1096
 * for a sent but unacknowledged packet on the given TCP session.
1097
 */
1098
int
1099
tcp_seq_vs_sess(inp, tcp_sequence)
1100
	struct inpcb *inp;
1101
	tcp_seq tcp_sequence;
1102
{
1103
	struct tcpcb *tp = intotcpcb(inp);
1104
	/*
1105
	 * If the sequence number is less than that of the last 
1106
	 * unacknowledged packet, or greater than that of the 
1107
	 * last sent, the given sequence number is not that
1108
	 * of a sent but unacknowledged packet for this session.
1109
	 */
1110
	if (SEQ_LT(tcp_sequence, tp->snd_una) ||
1111
			SEQ_GT(tcp_sequence, tp->snd_max)) {
1112
		return(0);
1113
	} else {
1114
		return(1);
1115
	}
1116
}
1117
1118
/*
1073
 * When a source quench is received, close congestion window
1119
 * When a source quench is received, close congestion window
1074
 * to one segment.  We will gradually open it again as we proceed.
1120
 * to one segment.  We will gradually open it again as we proceed.
1075
 */
1121
 */
Lines 1086-1092 Link Here
1086
1132
1087
/*
1133
/*
1088
 * When a ICMP unreachable is recieved, drop the
1134
 * When a ICMP unreachable is recieved, drop the
1089
 * TCP connection, but only if in SYN_SENT
1135
 * TCP connection, depending on the sysctl
1136
 * icmp_like_rst_syn_sent_only, it only drops
1137
 * the session if it's in SYN-SENT state
1090
 */
1138
 */
1091
void
1139
void
1092
tcp_drop_syn_sent(inp, errno)
1140
tcp_drop_syn_sent(inp, errno)
Lines 1094-1101 Link Here
1094
	int errno;
1142
	int errno;
1095
{
1143
{
1096
	struct tcpcb *tp = intotcpcb(inp);
1144
	struct tcpcb *tp = intotcpcb(inp);
1097
	if((tp) && (tp->t_state == TCPS_SYN_SENT))
1145
	if((tp) && ((icmp_like_rst_syn_sent_only == 0) || 
1098
			tcp_drop(tp, errno);
1146
			(tp->t_state == TCPS_SYN_SENT)))
1147
		tcp_drop(tp, errno);
1099
}
1148
}
1100
1149
1101
/*
1150
/*
(-)sys/netinet/tcp_var.h (+1 lines)
Lines 392-397 Link Here
392
struct tcpcb *
392
struct tcpcb *
393
	 tcp_newtcpcb __P((struct inpcb *));
393
	 tcp_newtcpcb __P((struct inpcb *));
394
int	 tcp_output __P((struct tcpcb *));
394
int	 tcp_output __P((struct tcpcb *));
395
int	 tcp_seq_vs_sess __P((struct inpcb *, tcp_seq));
395
void	 tcp_quench __P((struct inpcb *, int));
396
void	 tcp_quench __P((struct inpcb *, int));
396
void	 tcp_respond __P((struct tcpcb *, void *,
397
void	 tcp_respond __P((struct tcpcb *, void *,
397
	    struct tcphdr *, struct mbuf *, tcp_seq, tcp_seq, int));
398
	    struct tcphdr *, struct mbuf *, tcp_seq, tcp_seq, int));
(-)sys/netinet/udp_usrreq.c (-2 / +2 lines)
Lines 512-520 Link Here
512
	if (ip) {
512
	if (ip) {
513
		uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2));
513
		uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2));
514
		in_pcbnotify(&udb, sa, uh->uh_dport, ip->ip_src, uh->uh_sport,
514
		in_pcbnotify(&udb, sa, uh->uh_dport, ip->ip_src, uh->uh_sport,
515
			cmd, udp_notify);
515
			cmd, udp_notify, 0);
516
	} else
516
	} else
517
		in_pcbnotify(&udb, sa, 0, zeroin_addr, 0, cmd, udp_notify);
517
		in_pcbnotify(&udb, sa, 0, zeroin_addr, 0, cmd, udp_notify, 0);
518
}
518
}
519
519
520
static int
520
static int

Return to bug 23655