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 ---