Deleted Added
full compact
ip_state.c (64580) ip_state.c (67614)
1/*
2 * Copyright (C) 1995-2000 by Darren Reed.
3 *
4 * Redistribution and use in source and binary forms are permitted
5 * provided that this notice is preserved and due credit is given
6 * to the original author and the contributors.
7 */
8#if !defined(lint)
9static const char sccsid[] = "@(#)ip_state.c 1.8 6/5/96 (C) 1993-1995 Darren Reed";
1/*
2 * Copyright (C) 1995-2000 by Darren Reed.
3 *
4 * Redistribution and use in source and binary forms are permitted
5 * provided that this notice is preserved and due credit is given
6 * to the original author and the contributors.
7 */
8#if !defined(lint)
9static const char sccsid[] = "@(#)ip_state.c 1.8 6/5/96 (C) 1993-1995 Darren Reed";
10static const char rcsid[] = "@(#)$FreeBSD: head/sys/contrib/ipfilter/netinet/ip_state.c 64580 2000-08-13 04:31:06Z darrenr $";
10static const char rcsid[] = "@(#)$FreeBSD: head/sys/contrib/ipfilter/netinet/ip_state.c 67614 2000-10-26 12:33:42Z darrenr $";
11#endif
12
13#include <sys/errno.h>
14#include <sys/types.h>
15#include <sys/param.h>
16#include <sys/file.h>
17#if defined(__NetBSD__) && (NetBSD >= 199905) && !defined(IPFILTER_LKM) && \
18 defined(_KERNEL)

--- 82 unchanged lines hidden (view full) ---

101# define MIN(a,b) (((a)<(b))?(a):(b))
102#endif
103
104#define TCP_CLOSE (TH_FIN|TH_RST)
105
106static ipstate_t **ips_table = NULL;
107static ipstate_t *ips_list = NULL;
108static int ips_num = 0;
11#endif
12
13#include <sys/errno.h>
14#include <sys/types.h>
15#include <sys/param.h>
16#include <sys/file.h>
17#if defined(__NetBSD__) && (NetBSD >= 199905) && !defined(IPFILTER_LKM) && \
18 defined(_KERNEL)

--- 82 unchanged lines hidden (view full) ---

101# define MIN(a,b) (((a)<(b))?(a):(b))
102#endif
103
104#define TCP_CLOSE (TH_FIN|TH_RST)
105
106static ipstate_t **ips_table = NULL;
107static ipstate_t *ips_list = NULL;
108static int ips_num = 0;
109static int ips_wild = 0;
109static ips_stat_t ips_stats;
110#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
111extern KRWLOCK_T ipf_state, ipf_mutex;
112extern kmutex_t ipf_rw;
113#endif
114
115#ifdef USE_INET6
116static frentry_t *fr_checkicmp6matchingstate __P((ip6_t *, fr_info_t *));
117#endif
118static int fr_matchsrcdst __P((ipstate_t *, union i6addr, union i6addr,
119 fr_info_t *, tcphdr_t *));
120static frentry_t *fr_checkicmpmatchingstate __P((ip_t *, fr_info_t *));
121static int fr_matchicmpqueryreply __P((int, ipstate_t *, icmphdr_t *));
122static int fr_state_flush __P((int));
123static ips_stat_t *fr_statetstats __P((void));
124static void fr_delstate __P((ipstate_t *));
125static int fr_state_remove __P((caddr_t));
110static ips_stat_t ips_stats;
111#if (SOLARIS || defined(__sgi)) && defined(_KERNEL)
112extern KRWLOCK_T ipf_state, ipf_mutex;
113extern kmutex_t ipf_rw;
114#endif
115
116#ifdef USE_INET6
117static frentry_t *fr_checkicmp6matchingstate __P((ip6_t *, fr_info_t *));
118#endif
119static int fr_matchsrcdst __P((ipstate_t *, union i6addr, union i6addr,
120 fr_info_t *, tcphdr_t *));
121static frentry_t *fr_checkicmpmatchingstate __P((ip_t *, fr_info_t *));
122static int fr_matchicmpqueryreply __P((int, ipstate_t *, icmphdr_t *));
123static int fr_state_flush __P((int));
124static ips_stat_t *fr_statetstats __P((void));
125static void fr_delstate __P((ipstate_t *));
126static int fr_state_remove __P((caddr_t));
127static void fr_ipsmove __P((ipstate_t **, ipstate_t *, u_int));
126int fr_stputent __P((caddr_t));
127int fr_stgetent __P((caddr_t));
128void fr_stinsert __P((ipstate_t *));
129
130
131#define FIVE_DAYS (2 * 5 * 86400) /* 5 days: half closed session */
132
133#define TCP_MSL 240 /* 2 minutes */
134u_long fr_tcpidletimeout = FIVE_DAYS,
135 fr_tcpclosewait = 2 * TCP_MSL,
136 fr_tcplastack = 2 * TCP_MSL,
137 fr_tcptimeout = 2 * TCP_MSL,
128int fr_stputent __P((caddr_t));
129int fr_stgetent __P((caddr_t));
130void fr_stinsert __P((ipstate_t *));
131
132
133#define FIVE_DAYS (2 * 5 * 86400) /* 5 days: half closed session */
134
135#define TCP_MSL 240 /* 2 minutes */
136u_long fr_tcpidletimeout = FIVE_DAYS,
137 fr_tcpclosewait = 2 * TCP_MSL,
138 fr_tcplastack = 2 * TCP_MSL,
139 fr_tcptimeout = 2 * TCP_MSL,
138 fr_tcpclosed = 1,
140 fr_tcpclosed = 120,
141 fr_tcphalfclosed = 2 * 2 * 3600, /* 2 hours */
139 fr_udptimeout = 240,
140 fr_icmptimeout = 120;
141int fr_statemax = IPSTATE_MAX,
142 fr_statesize = IPSTATE_SIZE;
143int fr_state_doflush = 0,
144 fr_state_lock = 0;
145
146static int icmpreplytype4[ICMP_MAXTYPE + 1];

--- 88 unchanged lines hidden (view full) ---

235
236 sp = &st;
237 error = IRCOPYPTR(data, (caddr_t)&st, sizeof(st));
238 if (error)
239 return EFAULT;
240
241 for (sp = ips_list; sp; sp = sp->is_next)
242 if ((sp->is_p == st.is_p) && (sp->is_v == st.is_v) &&
142 fr_udptimeout = 240,
143 fr_icmptimeout = 120;
144int fr_statemax = IPSTATE_MAX,
145 fr_statesize = IPSTATE_SIZE;
146int fr_state_doflush = 0,
147 fr_state_lock = 0;
148
149static int icmpreplytype4[ICMP_MAXTYPE + 1];

--- 88 unchanged lines hidden (view full) ---

238
239 sp = &st;
240 error = IRCOPYPTR(data, (caddr_t)&st, sizeof(st));
241 if (error)
242 return EFAULT;
243
244 for (sp = ips_list; sp; sp = sp->is_next)
245 if ((sp->is_p == st.is_p) && (sp->is_v == st.is_v) &&
243 !bcmp(&sp->is_src, &st.is_src, sizeof(st.is_src)) &&
244 !bcmp(&sp->is_dst, &st.is_src, sizeof(st.is_dst)) &&
245 !bcmp(&sp->is_ps, &st.is_ps, sizeof(st.is_ps))) {
246 !bcmp((char *)&sp->is_src, (char *)&st.is_src,
247 sizeof(st.is_src)) &&
248 !bcmp((char *)&sp->is_dst, (char *)&st.is_src,
249 sizeof(st.is_dst)) &&
250 !bcmp((char *)&sp->is_ps, (char *)&st.is_ps,
251 sizeof(st.is_ps))) {
246 WRITE_ENTER(&ipf_state);
247#ifdef IPFILTER_LOG
248 ipstate_log(sp, ISL_REMOVE);
249#endif
250 fr_delstate(sp);
251 RWLOCK_EXIT(&ipf_state);
252 return 0;
253 }

--- 331 unchanged lines hidden (view full) ---

585 * sequence numbers do as we do mathematics on them later.
586 */
587 is->is_dport = tcp->th_dport;
588 is->is_sport = tcp->th_sport;
589 if ((flags & (FI_W_DPORT|FI_W_SPORT)) == 0) {
590 hv += tcp->th_dport;
591 hv += tcp->th_sport;
592 }
252 WRITE_ENTER(&ipf_state);
253#ifdef IPFILTER_LOG
254 ipstate_log(sp, ISL_REMOVE);
255#endif
256 fr_delstate(sp);
257 RWLOCK_EXIT(&ipf_state);
258 return 0;
259 }

--- 331 unchanged lines hidden (view full) ---

591 * sequence numbers do as we do mathematics on them later.
592 */
593 is->is_dport = tcp->th_dport;
594 is->is_sport = tcp->th_sport;
595 if ((flags & (FI_W_DPORT|FI_W_SPORT)) == 0) {
596 hv += tcp->th_dport;
597 hv += tcp->th_sport;
598 }
593 is->is_send = ntohl(tcp->th_seq) + ip->ip_len -
594 fin->fin_hlen - (tcp->th_off << 2) +
599 is->is_send = ntohl(tcp->th_seq) + fin->fin_dlen -
600 (tcp->th_off << 2) +
595 ((tcp->th_flags & TH_SYN) ? 1 : 0) +
596 ((tcp->th_flags & TH_FIN) ? 1 : 0);
597 is->is_maxsend = is->is_send;
598 is->is_dend = 0;
599 is->is_maxdwin = 1;
600 is->is_maxswin = ntohs(tcp->th_win);
601 if (is->is_maxswin == 0)
602 is->is_maxswin = 1;

--- 52 unchanged lines hidden (view full) ---

655 is->is_optmsk = 0xffffffff;
656 is->is_sec = fin->fin_fi.fi_secmsk;
657 is->is_secmsk = 0xffff;
658 is->is_auth = fin->fin_fi.fi_auth;
659 is->is_authmsk = 0xffff;
660 is->is_flags = fin->fin_fi.fi_fl & FI_CMP;
661 is->is_flags |= FI_CMP << 4;
662 is->is_flags |= flags & (FI_WILDP|FI_WILDA);
601 ((tcp->th_flags & TH_SYN) ? 1 : 0) +
602 ((tcp->th_flags & TH_FIN) ? 1 : 0);
603 is->is_maxsend = is->is_send;
604 is->is_dend = 0;
605 is->is_maxdwin = 1;
606 is->is_maxswin = ntohs(tcp->th_win);
607 if (is->is_maxswin == 0)
608 is->is_maxswin = 1;

--- 52 unchanged lines hidden (view full) ---

661 is->is_optmsk = 0xffffffff;
662 is->is_sec = fin->fin_fi.fi_secmsk;
663 is->is_secmsk = 0xffff;
664 is->is_auth = fin->fin_fi.fi_auth;
665 is->is_authmsk = 0xffff;
666 is->is_flags = fin->fin_fi.fi_fl & FI_CMP;
667 is->is_flags |= FI_CMP << 4;
668 is->is_flags |= flags & (FI_WILDP|FI_WILDA);
669 if (flags & (FI_WILDP|FI_WILDA))
670 ips_wild++;
663 is->is_ifp[1 - out] = NULL;
664 is->is_ifp[out] = fin->fin_ifp;
665#ifdef _KERNEL
666 strncpy(is->is_ifname[out], IFNAME(fin->fin_ifp), IFNAMSIZ);
667#endif
668 is->is_ifname[1 - out][0] = '\0';
669 if (pass & FR_LOGFIRST)
670 is->is_pass &= ~(FR_LOGFIRST|FR_LOG);

--- 42 unchanged lines hidden (view full) ---

713 tdata = &is->is_tcp.ts_data[source];
714 seq = ntohl(tcp->th_seq);
715 ack = ntohl(tcp->th_ack);
716 win = ntohs(tcp->th_win);
717 end = seq + fin->fin_dlen - (tcp->th_off << 2) +
718 ((tcp->th_flags & TH_SYN) ? 1 : 0) +
719 ((tcp->th_flags & TH_FIN) ? 1 : 0);
720
671 is->is_ifp[1 - out] = NULL;
672 is->is_ifp[out] = fin->fin_ifp;
673#ifdef _KERNEL
674 strncpy(is->is_ifname[out], IFNAME(fin->fin_ifp), IFNAMSIZ);
675#endif
676 is->is_ifname[1 - out][0] = '\0';
677 if (pass & FR_LOGFIRST)
678 is->is_pass &= ~(FR_LOGFIRST|FR_LOG);

--- 42 unchanged lines hidden (view full) ---

721 tdata = &is->is_tcp.ts_data[source];
722 seq = ntohl(tcp->th_seq);
723 ack = ntohl(tcp->th_ack);
724 win = ntohs(tcp->th_win);
725 end = seq + fin->fin_dlen - (tcp->th_off << 2) +
726 ((tcp->th_flags & TH_SYN) ? 1 : 0) +
727 ((tcp->th_flags & TH_FIN) ? 1 : 0);
728
729 MUTEX_ENTER(&is->is_lock);
721 if (fdata->td_end == 0) {
722 /*
723 * Must be a (outgoing) SYN-ACK in reply to a SYN.
724 */
725 fdata->td_end = end;
726 fdata->td_maxwin = 1;
727 fdata->td_maxend = end + 1;
728 }

--- 49 unchanged lines hidden (view full) ---

778 }
779
780 ATOMIC_INCL(ips_stats.iss_hits);
781 is->is_pkts++;
782 is->is_bytes += fin->fin_dlen + fin->fin_hlen;
783 /*
784 * Nearing end of connection, start timeout.
785 */
730 if (fdata->td_end == 0) {
731 /*
732 * Must be a (outgoing) SYN-ACK in reply to a SYN.
733 */
734 fdata->td_end = end;
735 fdata->td_maxwin = 1;
736 fdata->td_maxend = end + 1;
737 }

--- 49 unchanged lines hidden (view full) ---

787 }
788
789 ATOMIC_INCL(ips_stats.iss_hits);
790 is->is_pkts++;
791 is->is_bytes += fin->fin_dlen + fin->fin_hlen;
792 /*
793 * Nearing end of connection, start timeout.
794 */
786 MUTEX_ENTER(&is->is_lock);
787 /* source ? 0 : 1 -> !source */
788 fr_tcp_age(&is->is_age, is->is_state, fin, !source);
795 /* source ? 0 : 1 -> !source */
796 fr_tcp_age(&is->is_age, is->is_state, fin, !source);
789 MUTEX_EXIT(&is->is_lock);
790 ret = 1;
791 }
797 ret = 1;
798 }
799 MUTEX_EXIT(&is->is_lock);
792 return ret;
793}
794
795
796static int fr_matchsrcdst(is, src, dst, fin, tcp)
797ipstate_t *is;
798union i6addr src, dst;
799fr_info_t *fin;

--- 87 unchanged lines hidden (view full) ---

887 is->is_dend = htonl(tcp->th_ack);
888 } else {
889 is->is_dport = sp;
890 is->is_dend = htonl(tcp->th_seq);
891 }
892 is->is_maxdend = is->is_dend + 1;
893 }
894 is->is_flags &= ~(FI_W_SPORT|FI_W_DPORT);
800 return ret;
801}
802
803
804static int fr_matchsrcdst(is, src, dst, fin, tcp)
805ipstate_t *is;
806union i6addr src, dst;
807fr_info_t *fin;

--- 87 unchanged lines hidden (view full) ---

895 is->is_dend = htonl(tcp->th_ack);
896 } else {
897 is->is_dport = sp;
898 is->is_dend = htonl(tcp->th_seq);
899 }
900 is->is_maxdend = is->is_dend + 1;
901 }
902 is->is_flags &= ~(FI_W_SPORT|FI_W_DPORT);
903 ips_wild--;
895 }
896
897 ret = -1;
898
899 if (!rev) {
900 if (out) {
901 if (!is->is_ifpout)
902 ret = 1;

--- 75 unchanged lines hidden (view full) ---

978 ip_t *oip;
979 u_int hv;
980
981 /*
982 * Does it at least have the return (basic) IP header ?
983 * Only a basic IP header (no options) should be with
984 * an ICMP error header.
985 */
904 }
905
906 ret = -1;
907
908 if (!rev) {
909 if (out) {
910 if (!is->is_ifpout)
911 ret = 1;

--- 75 unchanged lines hidden (view full) ---

987 ip_t *oip;
988 u_int hv;
989
990 /*
991 * Does it at least have the return (basic) IP header ?
992 * Only a basic IP header (no options) should be with
993 * an ICMP error header.
994 */
986 if (((ip->ip_v != 4) && (ip->ip_hl != 5)) ||
995 if (((ip->ip_v != 4) || (ip->ip_hl != 5)) ||
987 (fin->fin_plen < ICMPERR_MINPKTLEN))
988 return NULL;
989 ic = (struct icmp *)fin->fin_dp;
990 type = ic->icmp_type;
991 /*
992 * If it's not an error type, then return
993 */
994 if ((type != ICMP_UNREACH) && (type != ICMP_SOURCEQUENCH) &&

--- 37 unchanged lines hidden (view full) ---

1032 }
1033#endif
1034
1035 /*
1036 * in the IPv4 case we must zero the i6addr union otherwise
1037 * the IP6EQ and IP6NEQ macros produce the wrong results because
1038 * of the 'junk' in the unused part of the union
1039 */
996 (fin->fin_plen < ICMPERR_MINPKTLEN))
997 return NULL;
998 ic = (struct icmp *)fin->fin_dp;
999 type = ic->icmp_type;
1000 /*
1001 * If it's not an error type, then return
1002 */
1003 if ((type != ICMP_UNREACH) && (type != ICMP_SOURCEQUENCH) &&

--- 37 unchanged lines hidden (view full) ---

1041 }
1042#endif
1043
1044 /*
1045 * in the IPv4 case we must zero the i6addr union otherwise
1046 * the IP6EQ and IP6NEQ macros produce the wrong results because
1047 * of the 'junk' in the unused part of the union
1048 */
1040 bzero(&src, sizeof(src));
1041 bzero(&dst, sizeof(dst));
1049 bzero((char *)&src, sizeof(src));
1050 bzero((char *)&dst, sizeof(dst));
1042
1043 if (oip->ip_p == IPPROTO_ICMP) {
1044 icmp = (icmphdr_t *)((char *)oip + (oip->ip_hl << 2));
1045
1046 /*
1047 * a ICMP error can only be generated as a result of an
1048 * ICMP query, not as the response on an ICMP error
1049 *

--- 103 unchanged lines hidden (view full) ---

1153 RWLOCK_EXIT(&ipf_state);
1154 return fr;
1155 }
1156 }
1157 RWLOCK_EXIT(&ipf_state);
1158 return NULL;
1159}
1160
1051
1052 if (oip->ip_p == IPPROTO_ICMP) {
1053 icmp = (icmphdr_t *)((char *)oip + (oip->ip_hl << 2));
1054
1055 /*
1056 * a ICMP error can only be generated as a result of an
1057 * ICMP query, not as the response on an ICMP error
1058 *

--- 103 unchanged lines hidden (view full) ---

1162 RWLOCK_EXIT(&ipf_state);
1163 return fr;
1164 }
1165 }
1166 RWLOCK_EXIT(&ipf_state);
1167 return NULL;
1168}
1169
1170
1171static void fr_ipsmove(isp, is, hv)
1172ipstate_t **isp, *is;
1173u_int hv;
1174{
1175 u_int hvm;
1176
1177 hvm = is->is_hv;
1178 /*
1179 * Remove the hash from the old location...
1180 */
1181 if (is->is_hnext)
1182 is->is_hnext->is_phnext = isp;
1183 *isp = is->is_hnext;
1184 if (ips_table[hvm] == NULL)
1185 ips_stats.iss_inuse--;
1186
1187 /*
1188 * ...and put the hash in the new one.
1189 */
1190 hvm = hv % fr_statesize;
1191 isp = &ips_table[hvm];
1192 if (*isp)
1193 (*isp)->is_phnext = &is->is_hnext;
1194 else
1195 ips_stats.iss_inuse++;
1196 is->is_phnext = isp;
1197 is->is_hnext = *isp;
1198 *isp = is;
1199}
1200
1201
1161/*
1162 * Check if a packet has a registered state.
1163 */
1164frentry_t *fr_checkstate(ip, fin)
1165ip_t *ip;
1166fr_info_t *fin;
1167{
1168 union i6addr dst, src;

--- 66 unchanged lines hidden (view full) ---

1235 else
1236#endif
1237 fr = fr_checkicmpmatchingstate(ip, fin);
1238 if (fr)
1239 return fr;
1240 break;
1241 case IPPROTO_TCP :
1242 {
1202/*
1203 * Check if a packet has a registered state.
1204 */
1205frentry_t *fr_checkstate(ip, fin)
1206ip_t *ip;
1207fr_info_t *fin;
1208{
1209 union i6addr dst, src;

--- 66 unchanged lines hidden (view full) ---

1276 else
1277#endif
1278 fr = fr_checkicmpmatchingstate(ip, fin);
1279 if (fr)
1280 return fr;
1281 break;
1282 case IPPROTO_TCP :
1283 {
1243 register u_short dport = tcp->th_dport, sport = tcp->th_sport;
1284 register u_short dport, sport;
1244 register int i;
1245
1246 i = tcp->th_flags;
1247 /*
1248 * Just plain ignore RST flag set with either FIN or SYN.
1249 */
1250 if ((i & TH_RST) &&
1251 ((i & (TH_FIN|TH_SYN|TH_RST)) != TH_RST))
1252 break;
1285 register int i;
1286
1287 i = tcp->th_flags;
1288 /*
1289 * Just plain ignore RST flag set with either FIN or SYN.
1290 */
1291 if ((i & TH_RST) &&
1292 ((i & (TH_FIN|TH_SYN|TH_RST)) != TH_RST))
1293 break;
1294 case IPPROTO_UDP :
1295 dport = tcp->th_dport;
1296 sport = tcp->th_sport;
1253 tryagain = 0;
1297 tryagain = 0;
1254retry_tcp:
1255 hvm = hv % fr_statesize;
1256 WRITE_ENTER(&ipf_state);
1257 for (isp = &ips_table[hvm]; (is = *isp);
1258 isp = &is->is_hnext)
1259
1260
1261 if ((is->is_p == pr) && (is->is_v == v) &&
1262 fr_matchsrcdst(is, src, dst, fin, tcp)) {
1263 if (fr_tcpstate(is, fin, ip, tcp))
1264 break;
1265 is = NULL;
1266 break;
1267 }
1268 if (is != NULL)
1269 break;
1270 RWLOCK_EXIT(&ipf_state);
1271 hv += dport;
1272 hv += sport;
1298 hv += dport;
1299 hv += sport;
1273 if (tryagain == 0) {
1274 tryagain = 1;
1275 goto retry_tcp;
1276 }
1277 break;
1278 }
1279 case IPPROTO_UDP :
1280 {
1281 register u_short dport = tcp->th_dport, sport = tcp->th_sport;
1282
1283 tryagain = 0;
1284retry_udp:
1285 hvm = hv % fr_statesize;
1286 /*
1287 * Nothing else to match on but ports. and IP#'s
1288 */
1289 READ_ENTER(&ipf_state);
1300 READ_ENTER(&ipf_state);
1290 for (is = ips_table[hvm]; is; is = is->is_hnext)
1301retry_tcpudp:
1302 hvm = hv % fr_statesize;
1303 for (isp = &ips_table[hvm]; (is = *isp); isp = &is->is_hnext)
1291 if ((is->is_p == pr) && (is->is_v == v) &&
1292 fr_matchsrcdst(is, src, dst, fin, tcp)) {
1304 if ((is->is_p == pr) && (is->is_v == v) &&
1305 fr_matchsrcdst(is, src, dst, fin, tcp)) {
1293 is->is_age = fr_udptimeout;
1306 if ((pr == IPPROTO_TCP)) {
1307 if (!fr_tcpstate(is, fin, ip, tcp)) {
1308 continue;
1309 }
1310 }
1294 break;
1295 }
1311 break;
1312 }
1296 if (is != NULL)
1313 if (is != NULL) {
1314 if (tryagain &&
1315 !(is->is_flags & (FI_WILDP|FI_WILDA))) {
1316 hv += dport;
1317 hv += sport;
1318 fr_ipsmove(isp, is, hv);
1319 MUTEX_DOWNGRADE(&ipf_state);
1320 }
1297 break;
1321 break;
1322 }
1298 RWLOCK_EXIT(&ipf_state);
1323 RWLOCK_EXIT(&ipf_state);
1299 hv += dport;
1300 hv += sport;
1301 if (tryagain == 0) {
1324 if (!tryagain && ips_wild) {
1325 hv -= dport;
1326 hv -= sport;
1302 tryagain = 1;
1327 tryagain = 1;
1303 goto retry_udp;
1328 WRITE_ENTER(&ipf_state);
1329 goto retry_tcpudp;
1304 }
1305 break;
1306 }
1307 default :
1308 break;
1309 }
1310 if (is == NULL) {
1311 ATOMIC_INCL(ips_stats.iss_miss);

--- 40 unchanged lines hidden (view full) ---

1352}
1353
1354
1355static void fr_delstate(is)
1356ipstate_t *is;
1357{
1358 frentry_t *fr;
1359
1330 }
1331 break;
1332 }
1333 default :
1334 break;
1335 }
1336 if (is == NULL) {
1337 ATOMIC_INCL(ips_stats.iss_miss);

--- 40 unchanged lines hidden (view full) ---

1378}
1379
1380
1381static void fr_delstate(is)
1382ipstate_t *is;
1383{
1384 frentry_t *fr;
1385
1386 if (is->is_flags & (FI_WILDP|FI_WILDA))
1387 ips_wild--;
1360 if (is->is_next)
1361 is->is_next->is_pnext = is->is_pnext;
1362 *is->is_pnext = is->is_next;
1363 if (is->is_hnext)
1364 is->is_hnext->is_phnext = is->is_phnext;
1365 *is->is_phnext = is->is_hnext;
1366 if (ips_table[is->is_hv] == NULL)
1367 ips_stats.iss_inuse--;

--- 193 unchanged lines hidden (view full) ---

1561 *age = fr_tcpidletimeout;
1562 } else if (flags & TH_FIN) {
1563 /*
1564 * We see an F from 'dir' which is in SYN_RECEIVED
1565 * state and wants to close its side of the connection;
1566 * SYN_RECEIVED -> FIN_WAIT_1
1567 */
1568 state[dir] = TCPS_FIN_WAIT_1;
1388 if (is->is_next)
1389 is->is_next->is_pnext = is->is_pnext;
1390 *is->is_pnext = is->is_next;
1391 if (is->is_hnext)
1392 is->is_hnext->is_phnext = is->is_phnext;
1393 *is->is_phnext = is->is_hnext;
1394 if (ips_table[is->is_hv] == NULL)
1395 ips_stats.iss_inuse--;

--- 193 unchanged lines hidden (view full) ---

1589 *age = fr_tcpidletimeout;
1590 } else if (flags & TH_FIN) {
1591 /*
1592 * We see an F from 'dir' which is in SYN_RECEIVED
1593 * state and wants to close its side of the connection;
1594 * SYN_RECEIVED -> FIN_WAIT_1
1595 */
1596 state[dir] = TCPS_FIN_WAIT_1;
1569 *age = fr_tcpidletimeout; /* or fr_tcptimeout? */
1597 *age = fr_tcpidletimeout;
1570 }
1571 break;
1572
1573 case TCPS_ESTABLISHED: /* 4 */
1574 if (flags & TH_FIN) {
1575 /*
1576 * 'dir' closed its side of the connection; this
1577 * gives us a half-closed connection;
1578 * ESTABLISHED -> FIN_WAIT_1
1579 */
1580 state[dir] = TCPS_FIN_WAIT_1;
1598 }
1599 break;
1600
1601 case TCPS_ESTABLISHED: /* 4 */
1602 if (flags & TH_FIN) {
1603 /*
1604 * 'dir' closed its side of the connection; this
1605 * gives us a half-closed connection;
1606 * ESTABLISHED -> FIN_WAIT_1
1607 */
1608 state[dir] = TCPS_FIN_WAIT_1;
1581 *age = fr_tcpidletimeout;
1609 *age = fr_tcphalfclosed;
1582 } else if (flags & TH_ACK) {
1583 /* an ACK, should we exclude other flags here? */
1584 if (ostate == TCPS_FIN_WAIT_1) {
1585 /*
1586 * We know the other side did an active close,
1587 * so we are ACKing the recvd FIN packet (does
1588 * the window matching code guarantee this?)
1589 * and go into CLOSE_WAIT state; this gives us
1590 * a half-closed connection
1591 */
1592 state[dir] = TCPS_CLOSE_WAIT;
1610 } else if (flags & TH_ACK) {
1611 /* an ACK, should we exclude other flags here? */
1612 if (ostate == TCPS_FIN_WAIT_1) {
1613 /*
1614 * We know the other side did an active close,
1615 * so we are ACKing the recvd FIN packet (does
1616 * the window matching code guarantee this?)
1617 * and go into CLOSE_WAIT state; this gives us
1618 * a half-closed connection
1619 */
1620 state[dir] = TCPS_CLOSE_WAIT;
1593 *age = fr_tcpidletimeout;
1621 *age = fr_tcphalfclosed;
1594 } else if (ostate < TCPS_CLOSE_WAIT)
1595 /*
1596 * Still a fully established connection,
1597 * reset timeout
1598 */
1599 *age = fr_tcpidletimeout;
1600 }
1601 break;

--- 7 unchanged lines hidden (view full) ---

1609 *age = fr_tcplastack;
1610 state[dir] = TCPS_LAST_ACK;
1611 } else {
1612 /*
1613 * We remain in CLOSE_WAIT because the other side has
1614 * closed already and we did not close our side yet;
1615 * reset timeout
1616 */
1622 } else if (ostate < TCPS_CLOSE_WAIT)
1623 /*
1624 * Still a fully established connection,
1625 * reset timeout
1626 */
1627 *age = fr_tcpidletimeout;
1628 }
1629 break;

--- 7 unchanged lines hidden (view full) ---

1637 *age = fr_tcplastack;
1638 state[dir] = TCPS_LAST_ACK;
1639 } else {
1640 /*
1641 * We remain in CLOSE_WAIT because the other side has
1642 * closed already and we did not close our side yet;
1643 * reset timeout
1644 */
1617 *age = fr_tcpidletimeout;
1645 *age = fr_tcphalfclosed;
1618 }
1619 break;
1620
1621 case TCPS_FIN_WAIT_1: /* 6 */
1622 if ((flags & TH_ACK) && ostate > TCPS_CLOSE_WAIT) {
1623 /*
1624 * If the other side is not active anymore it has sent
1625 * us a FIN packet that we are ack'ing now with an ACK;

--- 7 unchanged lines hidden (view full) ---

1633 state[dir] = TCPS_TIME_WAIT;
1634 *age = fr_tcptimeout;
1635 } else
1636 /*
1637 * We closed our side of the connection already but the
1638 * other side is still active (ESTABLISHED/CLOSE_WAIT);
1639 * continue with this half-closed connection
1640 */
1646 }
1647 break;
1648
1649 case TCPS_FIN_WAIT_1: /* 6 */
1650 if ((flags & TH_ACK) && ostate > TCPS_CLOSE_WAIT) {
1651 /*
1652 * If the other side is not active anymore it has sent
1653 * us a FIN packet that we are ack'ing now with an ACK;

--- 7 unchanged lines hidden (view full) ---

1661 state[dir] = TCPS_TIME_WAIT;
1662 *age = fr_tcptimeout;
1663 } else
1664 /*
1665 * We closed our side of the connection already but the
1666 * other side is still active (ESTABLISHED/CLOSE_WAIT);
1667 * continue with this half-closed connection
1668 */
1641 *age = fr_tcpidletimeout;
1669 *age = fr_tcphalfclosed;
1642 break;
1643
1644 case TCPS_CLOSING: /* 7 */
1645 /* NOT USED */
1646 break;
1647
1648 case TCPS_LAST_ACK: /* 8 */
1649 if (flags & TH_ACK) {

--- 225 unchanged lines hidden ---
1670 break;
1671
1672 case TCPS_CLOSING: /* 7 */
1673 /* NOT USED */
1674 break;
1675
1676 case TCPS_LAST_ACK: /* 8 */
1677 if (flags & TH_ACK) {

--- 225 unchanged lines hidden ---