tcp_syncache.c (e0982661911e3ca7edbd664b7adba879ed9467bb) | tcp_syncache.c (c94c54e4df9ae401d299ca3b08f00acade2fccc8) |
---|---|
1/*- 2 * Copyright (c) 2001 Networks Associates Technology, Inc. 3 * All rights reserved. 4 * 5 * This software was developed for the FreeBSD Project by Jonathan Lemon 6 * and NAI Labs, the Security Research Division of Network Associates, Inc. 7 * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the 8 * DARPA CHATS research program. --- 680 unchanged lines hidden (view full) --- 689 tp->requested_s_scale = sc->sc_requested_s_scale; 690 tp->request_r_scale = sc->sc_request_r_scale; 691 } 692 if (sc->sc_flags & SCF_TIMESTAMP) { 693 tp->t_flags |= TF_REQ_TSTMP|TF_RCVD_TSTMP; 694 tp->ts_recent = sc->sc_tsrecent; 695 tp->ts_recent_age = ticks; 696 } | 1/*- 2 * Copyright (c) 2001 Networks Associates Technology, Inc. 3 * All rights reserved. 4 * 5 * This software was developed for the FreeBSD Project by Jonathan Lemon 6 * and NAI Labs, the Security Research Division of Network Associates, Inc. 7 * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the 8 * DARPA CHATS research program. --- 680 unchanged lines hidden (view full) --- 689 tp->requested_s_scale = sc->sc_requested_s_scale; 690 tp->request_r_scale = sc->sc_request_r_scale; 691 } 692 if (sc->sc_flags & SCF_TIMESTAMP) { 693 tp->t_flags |= TF_REQ_TSTMP|TF_RCVD_TSTMP; 694 tp->ts_recent = sc->sc_tsrecent; 695 tp->ts_recent_age = ticks; 696 } |
697 if (sc->sc_flags & SCF_CC) { 698 /* 699 * Initialization of the tcpcb for transaction; 700 * set SND.WND = SEG.WND, 701 * initialize CCsend and CCrecv. 702 */ 703 tp->t_flags |= TF_REQ_CC|TF_RCVD_CC; 704 tp->cc_send = sc->sc_cc_send; 705 tp->cc_recv = sc->sc_cc_recv; 706 } | |
707#ifdef TCP_SIGNATURE 708 if (sc->sc_flags & SCF_SIGNATURE) 709 tp->t_flags |= TF_SIGNATURE; 710#endif 711 if (sc->sc_flags & SCF_SACK) { 712 tp->sack_enable = 1; 713 tp->t_flags |= TF_SACK_PERMIT; 714 } --- 111 unchanged lines hidden (view full) --- 826 struct socket **sop; 827 struct mbuf *m; 828{ 829 struct tcpcb *tp; 830 struct socket *so; 831 struct syncache *sc = NULL; 832 struct syncache_head *sch; 833 struct mbuf *ipopts = NULL; | 697#ifdef TCP_SIGNATURE 698 if (sc->sc_flags & SCF_SIGNATURE) 699 tp->t_flags |= TF_SIGNATURE; 700#endif 701 if (sc->sc_flags & SCF_SACK) { 702 tp->sack_enable = 1; 703 tp->t_flags |= TF_SACK_PERMIT; 704 } --- 111 unchanged lines hidden (view full) --- 816 struct socket **sop; 817 struct mbuf *m; 818{ 819 struct tcpcb *tp; 820 struct socket *so; 821 struct syncache *sc = NULL; 822 struct syncache_head *sch; 823 struct mbuf *ipopts = NULL; |
834 struct rmxp_tao tao; | |
835 u_int32_t flowtmp; 836 int i, win; 837 838 INP_INFO_WLOCK_ASSERT(&tcbinfo); 839 840 so = *sop; 841 tp = sototcpcb(so); | 824 u_int32_t flowtmp; 825 int i, win; 826 827 INP_INFO_WLOCK_ASSERT(&tcbinfo); 828 829 so = *sop; 830 tp = sototcpcb(so); |
842 bzero(&tao, sizeof(tao)); | |
843 844 /* 845 * Remember the IP options, if any. 846 */ 847#ifdef INET6 848 if (!inc->inc_isipv6) 849#endif 850 ipopts = ip_srcroute(m); --- 133 unchanged lines hidden (view full) --- 984 while (wscale < TCP_MAX_WINSHIFT && 985 (TCP_MAXWIN << wscale) < so->so_rcv.sb_hiwat) 986 wscale++; 987 sc->sc_request_r_scale = wscale; 988 sc->sc_requested_s_scale = to->to_requested_s_scale; 989 sc->sc_flags |= SCF_WINSCALE; 990 } 991 } | 831 832 /* 833 * Remember the IP options, if any. 834 */ 835#ifdef INET6 836 if (!inc->inc_isipv6) 837#endif 838 ipopts = ip_srcroute(m); --- 133 unchanged lines hidden (view full) --- 972 while (wscale < TCP_MAX_WINSHIFT && 973 (TCP_MAXWIN << wscale) < so->so_rcv.sb_hiwat) 974 wscale++; 975 sc->sc_request_r_scale = wscale; 976 sc->sc_requested_s_scale = to->to_requested_s_scale; 977 sc->sc_flags |= SCF_WINSCALE; 978 } 979 } |
992 if (tcp_do_rfc1644) { 993 /* 994 * A CC or CC.new option received in a SYN makes 995 * it ok to send CC in subsequent segments. 996 */ 997 if (to->to_flags & (TOF_CC|TOF_CCNEW)) { 998 sc->sc_cc_recv = to->to_cc; 999 sc->sc_cc_send = CC_INC(tcp_ccgen); 1000 sc->sc_flags |= SCF_CC; 1001 } 1002 } | |
1003 if (tp->t_flags & TF_NOOPT) 1004 sc->sc_flags = SCF_NOOPT; 1005#ifdef TCP_SIGNATURE 1006 /* 1007 * If listening socket requested TCP digests, and received SYN 1008 * contains the option, flag this in the syncache so that 1009 * syncache_respond() will do the right thing with the SYN+ACK. 1010 * XXX Currently we always record the option by default and will 1011 * attempt to use it in syncache_respond(). 1012 */ 1013 if (to->to_flags & TOF_SIGNATURE) 1014 sc->sc_flags = SCF_SIGNATURE; 1015#endif 1016 1017 if (to->to_flags & TOF_SACK) 1018 sc->sc_flags |= SCF_SACK; 1019 1020 /* | 980 if (tp->t_flags & TF_NOOPT) 981 sc->sc_flags = SCF_NOOPT; 982#ifdef TCP_SIGNATURE 983 /* 984 * If listening socket requested TCP digests, and received SYN 985 * contains the option, flag this in the syncache so that 986 * syncache_respond() will do the right thing with the SYN+ACK. 987 * XXX Currently we always record the option by default and will 988 * attempt to use it in syncache_respond(). 989 */ 990 if (to->to_flags & TOF_SIGNATURE) 991 sc->sc_flags = SCF_SIGNATURE; 992#endif 993 994 if (to->to_flags & TOF_SACK) 995 sc->sc_flags |= SCF_SACK; 996 997 /* |
1021 * XXX 1022 * We have the option here of not doing TAO (even if the segment 1023 * qualifies) and instead fall back to a normal 3WHS via the syncache. 1024 * This allows us to apply synflood protection to TAO-qualifying SYNs 1025 * also. However, there should be a hueristic to determine when to 1026 * do this, and is not present at the moment. | 998 * Do a standard 3-way handshake. |
1027 */ | 999 */ |
1028 1029 /* 1030 * Perform TAO test on incoming CC (SEG.CC) option, if any. 1031 * - compare SEG.CC against cached CC from the same host, if any. 1032 * - if SEG.CC > chached value, SYN must be new and is accepted 1033 * immediately: save new CC in the cache, mark the socket 1034 * connected, enter ESTABLISHED state, turn on flag to 1035 * send a SYN in the next segment. 1036 * A virtual advertised window is set in rcv_adv to 1037 * initialize SWS prevention. Then enter normal segment 1038 * processing: drop SYN, process data and FIN. 1039 * - otherwise do a normal 3-way handshake. 1040 */ 1041 if (tcp_do_rfc1644) 1042 tcp_hc_gettao(&sc->sc_inc, &tao); 1043 1044 if ((to->to_flags & TOF_CC) != 0) { 1045 if (((tp->t_flags & TF_NOPUSH) != 0) && 1046 sc->sc_flags & SCF_CC && tao.tao_cc != 0 && 1047 CC_GT(to->to_cc, tao.tao_cc)) { 1048 sc->sc_rxtslot = 0; 1049 so = syncache_socket(sc, *sop, m); 1050 if (so != NULL) { 1051 tao.tao_cc = to->to_cc; 1052 tcp_hc_updatetao(&sc->sc_inc, TCP_HC_TAO_CC, 1053 tao.tao_cc, 0); 1054 *sop = so; 1055 } 1056 syncache_free(sc); 1057 return (so != NULL); 1058 } 1059 } else { 1060 /* 1061 * No CC option, but maybe CC.NEW: invalidate cached value. 1062 */ 1063 if (tcp_do_rfc1644) { 1064 tao.tao_cc = 0; 1065 tcp_hc_updatetao(&sc->sc_inc, TCP_HC_TAO_CC, 1066 tao.tao_cc, 0); 1067 } 1068 } 1069 1070 /* 1071 * TAO test failed or there was no CC option, 1072 * do a standard 3-way handshake. 1073 */ | |
1074#ifdef TCPDEBUG 1075 if (syncache_respond(sc, m, so) == 0) { 1076#else 1077 if (syncache_respond(sc, m) == 0) { 1078#endif 1079 syncache_insert(sc, sch); 1080 tcpstat.tcps_sndacks++; 1081 tcpstat.tcps_sndtotal++; --- 40 unchanged lines hidden (view full) --- 1122 mssopt = tcp_mssopt(&sc->sc_inc); 1123 1124 /* Compute the size of the TCP options. */ 1125 if (sc->sc_flags & SCF_NOOPT) { 1126 optlen = 0; 1127 } else { 1128 optlen = TCPOLEN_MAXSEG + 1129 ((sc->sc_flags & SCF_WINSCALE) ? 4 : 0) + | 1000#ifdef TCPDEBUG 1001 if (syncache_respond(sc, m, so) == 0) { 1002#else 1003 if (syncache_respond(sc, m) == 0) { 1004#endif 1005 syncache_insert(sc, sch); 1006 tcpstat.tcps_sndacks++; 1007 tcpstat.tcps_sndtotal++; --- 40 unchanged lines hidden (view full) --- 1048 mssopt = tcp_mssopt(&sc->sc_inc); 1049 1050 /* Compute the size of the TCP options. */ 1051 if (sc->sc_flags & SCF_NOOPT) { 1052 optlen = 0; 1053 } else { 1054 optlen = TCPOLEN_MAXSEG + 1055 ((sc->sc_flags & SCF_WINSCALE) ? 4 : 0) + |
1130 ((sc->sc_flags & SCF_TIMESTAMP) ? TCPOLEN_TSTAMP_APPA : 0) + 1131 ((sc->sc_flags & SCF_CC) ? TCPOLEN_CC_APPA * 2 : 0); | 1056 ((sc->sc_flags & SCF_TIMESTAMP) ? TCPOLEN_TSTAMP_APPA : 0); |
1132#ifdef TCP_SIGNATURE 1133 optlen += (sc->sc_flags & SCF_SIGNATURE) ? 1134 TCPOLEN_SIGNATURE + 2 : 0; 1135#endif 1136 optlen += ((sc->sc_flags & SCF_SACK) ? 4 : 0); 1137 } 1138 tlen = hlen + sizeof(struct tcphdr) + optlen; 1139 --- 95 unchanged lines hidden (view full) --- 1235 1236 /* Form timestamp option per appendix A of RFC 1323. */ 1237 *lp++ = htonl(TCPOPT_TSTAMP_HDR); 1238 *lp++ = htonl(ticks); 1239 *lp = htonl(sc->sc_tsrecent); 1240 optp += TCPOLEN_TSTAMP_APPA; 1241 } 1242 | 1057#ifdef TCP_SIGNATURE 1058 optlen += (sc->sc_flags & SCF_SIGNATURE) ? 1059 TCPOLEN_SIGNATURE + 2 : 0; 1060#endif 1061 optlen += ((sc->sc_flags & SCF_SACK) ? 4 : 0); 1062 } 1063 tlen = hlen + sizeof(struct tcphdr) + optlen; 1064 --- 95 unchanged lines hidden (view full) --- 1160 1161 /* Form timestamp option per appendix A of RFC 1323. */ 1162 *lp++ = htonl(TCPOPT_TSTAMP_HDR); 1163 *lp++ = htonl(ticks); 1164 *lp = htonl(sc->sc_tsrecent); 1165 optp += TCPOLEN_TSTAMP_APPA; 1166 } 1167 |
1243 /* 1244 * Send CC and CC.echo if we received CC from our peer. 1245 */ 1246 if (sc->sc_flags & SCF_CC) { 1247 u_int32_t *lp = (u_int32_t *)(optp); 1248 1249 *lp++ = htonl(TCPOPT_CC_HDR(TCPOPT_CC)); 1250 *lp++ = htonl(sc->sc_cc_send); 1251 *lp++ = htonl(TCPOPT_CC_HDR(TCPOPT_CCECHO)); 1252 *lp = htonl(sc->sc_cc_recv); 1253 optp += TCPOLEN_CC_APPA * 2; 1254 } 1255 | |
1256#ifdef TCP_SIGNATURE 1257 /* 1258 * Handle TCP-MD5 passive opener response. 1259 */ 1260 if (sc->sc_flags & SCF_SIGNATURE) { 1261 u_int8_t *bp = optp; 1262 int i; 1263 --- 229 unchanged lines hidden --- | 1168#ifdef TCP_SIGNATURE 1169 /* 1170 * Handle TCP-MD5 passive opener response. 1171 */ 1172 if (sc->sc_flags & SCF_SIGNATURE) { 1173 u_int8_t *bp = optp; 1174 int i; 1175 --- 229 unchanged lines hidden --- |