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