首页 运维 网络学院 查看内容

SPARC/Solaris 8下快速终结TCP有限状态机的TIME_WAIT状态

2005-6-11 16:24 566 0

摘要: 我们这里讨论的是在程序不可控的情况下,比如别人的程序,又未使用SO_REUSEADDR选项,如何快 速终结TCP有限状态机的...
关键词: tcpb define TCP base tcpu offset bound uint WAIT remote

我们这里讨论的是在程序不可控的情况下,比如别人的程序,又未使用SO_REUSEADDR选项,如何快 速终结TCP有限状态机的TIME_WAIT状态。 参看这个链接"closing half-open connections" http://www-mice.cs.ucl.ac.uk/multimedia/misc/tcp_ip/8707.mm.www/0009.html 1987年10月1日(可真够早的)[email protected]提供了一个shell script,用于 SunOS 4.x系统下快速终结TCP有限状态机的TIME_WAIT状态。很奇怪,这个脚本并未 得到人们的足够重视并广泛流传,直到SunOS 4.x退出历史舞台,它也就销声匿迹了。 昨天被backend从故纸堆里翻了出来,我们就趁机移植到SPARC/Solaris 8下来。 参看UNP 图2.4了解TCP有限状态机的变迁过程。 /usr/include/netinet里的文件多是为用户空间编程准备的,/usr/include/inet里 的文件多是为内核空间编程准备的。下面内容取自SPARC/Solaris 8 -------------------------------------------------------------------------- /* * /usr/include/inet/tcp.h */ /* * TCP states */ #define TCPS_CLOSED -6 #define TCPS_IDLE -5 /* idle (opened, but not bound) */ #define TCPS_BOUND -4 /* bound, ready to connect or accept */ #define TCPS_LISTEN -3 /* listening for connection */ #define TCPS_SYN_SENT -2 /* active, have sent syn */ #define TCPS_SYN_RCVD -1 /* have received syn (and sent ours) */ /* * states < TCPS_ESTABLISHED are those where connections not established */ #define TCPS_ESTABLISHED 0 /* established */ #define TCPS_CLOSE_WAIT 1 /* rcvd fin, waiting for close */ /* * states > TCPS_CLOSE_WAIT are those where user has closed */ #define TCPS_FIN_WAIT_1 2 /* have closed and sent fin */ #define TCPS_CLOSING 3 /* closed, xchd FIN, await FIN ACK */ #define TCPS_LAST_ACK 4 /* had fin and close; await FIN ACK */ /* * states > TCPS_CLOSE_WAIT && < TCPS_FIN_WAIT_2 await ACK of FIN */ #define TCPS_FIN_WAIT_2 5 /* have closed, fin is acked */ #define TCPS_TIME_WAIT 6 /* in 2*msl quiet wait after close */ #if (defined(_KERNEL) || defined(_KMEMUSER)) /* * If the information represented by the field is required even in the * TIME_WAIT state, it must be part of tcpb_t. Otherwise it must be part * of tcp_t. In other words, the tcp_t captures the information that is * not required, after a connection has entered the TIME_WAIT state. */ typedef struct tcp_base_s { struct tcp_base_s *tcpb_bind_hash; /* Bind hash chain */ struct tcp_base_s **tcpb_ptpbhn; /* Pointer to previous bind hash next. */ struct tcp_base_s *tcpb_conn_hash; /* Connect hash chain */ struct tcp_base_s **tcpb_ptpchn; /* Pointer to previous conn hash next. */ struct tcp_base_s *tcpb_time_wait_next; /* Pointer to next T/W block */ struct tcp_base_s *tcpb_time_wait_prev; /* Pointer to previous T/W next */ /* * /usr/include/sys/types.h * typedef long clock_t; * offset: 8 * 6 -> 48 -> 0x30,clock_t占8个字节(64-bit kernel mode) */ clock_t tcpb_time_wait_expire; /* time in hz when t/w expires */ clock_t tcpb_last_rcv_lbolt; /* lbolt on last packet, used for PAWS */ /* * offset: 0x40 */ int32_t tcpb_state; int32_t tcpb_rcv_ws; /* My window scale power */ int32_t tcpb_snd_ws; /* Sender's window scale power */ uint32_t tcpb_ts_recent; /* Timestamp of earliest unacked */ /* * data segment * offset: 0x50 */ clock_t tcpb_rto; /* Round trip timeout */ uint32_t tcpb_snd_ts_ok : 1, tcpb_snd_ws_ok : 1, tcpb_is_secure : 1, tcpb_reuseaddr : 1, /* SO_REUSEADDR "socket" option. */ tcpb_exclbind : 1, /* ``exclusive'' binding */ tcpb_junk_fill_thru_bit_31 : 27; /* * offset: 0x5c */ uint32_t tcpb_snxt; /* Senders next seq num */ uint32_t tcpb_swnd; /* Senders window (relative to suna) */ uint32_t tcpb_mss; /* Max segment size */ uint32_t tcpb_iss; /* Initial send seq num */ /* * offset: 0x6c */ uint32_t tcpb_rnxt; /* Seq we expect to recv next */ uint32_t tcpb_rwnd; /* Current receive window */ /* * /usr/include/sys/mutex.h * 无论64-bit还是32-bit kernel mode,kmutex_t都占8字节空间,这里需要对 * 齐在数据类型自然连界上,0x6c + 8 -> 0x74不在kmutex_t自然边界上,继 * 续后移4个字节 * * offset: 0x78 */ kmutex_t tcpb_reflock; /* Protects tcp_refcnt */ /* * offset: 0x80 */ ushort_t tcpb_refcnt; /* Number of pending upstream msg */ union { struct { uchar_t v4_ttl; /* Dup of tcp_ipha.iph_type_of_service */ uchar_t v4_tos; /* Dup of tcp_ipha.iph_ttl */ } v4_hdr_info; struct { /* * 对齐在uint_t的自然边界上 * offset: 0x84 */ uint_t v6_vcf; /* Dup of tcp_ip6h.ip6h_vcf */ /* * offset: 0x88 */ uchar_t v6_hops; /* Dup of tcp_ip6h.ip6h_hops */ } v6_hdr_info; } tcpb_hdr_info; #define tcpb_ttl tcpb_hdr_info.v4_hdr_info.v4_ttl #define tcpb_tos tcpb_hdr_info.v4_hdr_info.v4_tos #define tcpb_ip6_vcf tcpb_hdr_info.v6_hdr_info.v6_vcf #define tcpb_ip6_hops tcpb_hdr_info.v6_hdr_info.v6_hops /* * offset: 0x8c,先是远端地址,后是本地地址 * /usr/include/netinet/in.h * in6_addr_t长16字节,在内核空间里这个结构对齐在uint32_t的自然边界上 */ in6_addr_t tcpb_remote_v6; /* true remote address - needed for */ /* source routing. */ in6_addr_t tcpb_bound_source_v6; /* IP address in bind_req */ /* * offset: 0xac */ in6_addr_t tcpb_ip_src_v6; /* same as tcp_iph.iph_src. */ #ifdef _KERNEL /* * Note: V4_PART_OF_V6 is meant to be used only for _KERNEL defined stuff */ #define tcpb_remote V4_PART_OF_V6(tcpb_remote_v6) #define tcpb_bound_source V4_PART_OF_V6(tcpb_bound_source_v6) #define tcpb_ip_src V4_PART_OF_V6(tcpb_ip_src_v6) #endif /* _KERNEL */ /* * These fields contain the same information as tcp_tcph->th_*port. * However, the lookup functions can not use the header fields * since during IP option manipulation the tcp_tcph pointer * changes. */ /* * offset: 0xbc,先是远端端口,后是本地端口 */ union { struct { in_port_t tcpu_fport; /* Remote port */ in_port_t tcpu_lport; /* Local port */ } tcpu_ports1; uint32_t tcpu_ports2; /* Rem port, local port */ /* * Used for TCP_MATCH performance */ } tcpb_tcpu; #define tcpb_fport tcpb_tcpu.tcpu_ports1.tcpu_fport #define tcpb_lport tcpb_tcpu.tcpu_ports1.tcpu_lport #define tcpb_ports tcpb_tcpu.tcpu_ports2 /* * IP sends back 2 mblks with the unbind ACK for handling * IPSEC policy for detached connections. Following two fields * are initialized then. */ mblk_t *tcpb_ipsec_out; mblk_t *tcpb_ipsec_req_in; /* * offset: 0xd0 */ tcp_t *tcpb_tcp; /* * offset: 0xd8 */ /* * IP format that packets transmitted from this struct should use. * Value can be IPV4_VERSION or IPV6_VERSION. Determines whether * IP+TCP header template above stores an IPv4 or IPv6 header. */ ushort_t tcpb_ipversion; uint_t tcpb_bound_if; /* IPV6_BOUND_IF */ uid_t tcpb_ownerid; /* uid of process that did open */ #define tcp_bind_hash tcp_base->tcpb_bind_hash #define tcp_ptpbhn tcp_base->tcpb_ptpbhn #define tcp_conn_hash tcp_base->tcpb_conn_hash #define tcp_ptpchn tcp_base->tcpb_ptpchn #define tcp_time_wait_next tcp_base->tcpb_time_wait_next #define tcp_time_wait_prev tcp_base->tcpb_time_wait_prev #define tcp_time_wait_expire tcp_base->tcpb_time_wait_expire #define tcp_last_rcv_lbolt tcp_base->tcpb_last_rcv_lbolt #define tcp_state tcp_base->tcpb_state #define tcp_rcv_ws tcp_base->tcpb_rcv_ws #define tcp_snd_ws tcp_base->tcpb_snd_ws #define tcp_ts_recent tcp_base->tcpb_ts_recent #define tcp_rto tcp_base->tcpb_rto #define tcp_snd_ts_ok tcp_base->tcpb_snd_ts_ok #define tcp_snd_ws_ok tcp_base->tcpb_snd_ws_ok #define tcp_is_secure tcp_base->tcpb_is_secure #define tcp_snxt tcp_base->tcpb_snxt #define tcp_swnd tcp_base->tcpb_swnd #define tcp_mss tcp_base->tcpb_mss #define tcp_iss tcp_base->tcpb_iss #define tcp_rnxt tcp_base->tcpb_rnxt #define tcp_rwnd tcp_base->tcpb_rwnd #define tcp_reflock tcp_base->tcpb_reflock #define tcp_refcnt tcp_base->tcpb_refcnt #define tcp_remote_v6 tcp_base->tcpb_remote_v6 #define tcp_remote tcp_base->tcpb_remote #define tcp_bound_source_v6 tcp_base->tcpb_bound_source_v6 #define tcp_bound_source tcp_base->tcpb_bound_source #define tcp_lport tcp_base->tcpb_tcpu.tcpu_ports1.tcpu_lport #define tcp_fport tcp_base->tcpb_tcpu.tcpu_ports1.tcpu_fport #define tcp_ports tcp_base->tcpb_tcpu.tcpu_ports2 #define tcp_ipsec_out tcp_base->tcpb_ipsec_out #define tcp_ipsec_req_in tcp_base->tcpb_ipsec_req_in #define tcp_ipversion tcp_base->tcpb
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

最新评论

返回顶部