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

SPARC/Solaris 8下快速终结TCP有限状态机的TIME_WAIT状态
 
2006年10月14日 12:56 ChinaByte  
 

  1987年10月1日(可真够早的)cdjohns@nswc-g.arpa提供了一个shell script,用于

  SunOS 4.x系统下快速终结TCP有限状态机的TIME_WAIT状态。很奇怪,这个脚本并未

  得到人们的足够重视并广泛流传,直到SunOS 4.x退出历史舞台,它也就销声匿迹了。

  昨天被backend从故纸堆里翻了出来,我们就趁机移植到SPARC/Solaris 8下来。

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

  #define tcp_bound_if tcp_base->tcpb_bound_if

  #define tcp_reuseaddr tcp_base->tcpb_reuseaddr

  #define tcp_exclbind tcp_base->tcpb_exclbind

  #define tcp_ownerid tcp_base->tcpb_ownerid

  } tcpb_t;

  #endif /* (defined(_KERNEL) || defined(_KMEMUSER)) */

  --------------------------------------------------------------------------

  下面这两条命令其实是用分号连在一起执行的,否则前后数据不对应,我是telnet上

  去执行命令。

  # ndd /dev/tcp tcp_status | grep ESTABLISHED

  TCPB dest snxt suna swnd rnxt rack rwnd rto mss w sw rw t recent [lport,fport] state

  30000cc21d0 ::ffff:192.168.5.8 8e0e46dc 8e0e46da 0000064010 3d49e751 3d49e751 0000024820 00583 01460 0 00 00 0 00000000 [23, 4613] TCP_ESTABLISHED

  # skd64 0x30000cc21d0 256

  byteArray [ 256 bytes ] ---->

  0000000000000000 00 00 03 00 00 47 C1 80-00 00 00 00 10 48 18 88 .....G羳.....H.?

  0000000000000010 00 00 00 00 00 00 00 00-00 00 03 00 00 3A 60 80 .............:`�

  0000000000000020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................

  0000000000000030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................

  0000000000000040 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................

  0000000000000050 00 00 00 00 00 00 02 47-10 00 00 00 8E 0E 46 DC .......G....?F?

  0000000000000060 00 00 FA 0A 00 00 05 B4-8E 0B 77 07 3D 49 E7 51 ..?...磶.w.=I鏠

  0000000000000070 00 00 60 F4 00 00 00 00-00 00 00 00 00 00 00 00 ..`?...........

  0000000000000080 00 01 00 00 3C 00 00 00-3C 00 00 00 00 00 00 00 ....<...<.......

  0000000000000090 00 00 00 00 00 00 FF FF-C0 A8 05 08 00 00 00 00 ......��括......

  00000000000000A0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................

  00000000000000B0 00 00 00 00 00 00 FF FF-C0 A8 05 82 12 05 00 17 ......��括.?...

  00000000000000C0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................

  00000000000000D0 00 00 03 00 00 BB 6F D0-00 04 00 00 00 00 00 00 .....籵?.......

  00000000000000E0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................

  00000000000000F0 00 00 03 00 00 08 2B 68-00 00 00 00 00 00 00 00 ......+h........

  #

  显然0x30000cc21d0对应着一个tcpb_t结构。

  # adb -k /dev/ksyms /dev/mem

  physmem 3b68

  0x30000cc21d0$

  30000cc21d0: tcp_bind_hash tcp_ptpbhn tcp_conn_hash

  3000047c180 10481888 0

  30000cc21e8: tcp_ptpchn time_wait_next time_wait_prev

  300003a6080 0 0

  30000cc2200: time_wait_expir last_rcv_lbolt tcp_state

  0 0 0

  30000cc2214: tcp_rcv_ws tcp_snd_ws tcp_ts_recent

  0 0 0

  30000cc2220: tcp_rto

  24c

  snd_ts_ok 0

  snd_ws_ok 0

  is_secure 0

  reuseaddr 1

  exclbind 0

  30000cc222c: tcp_snxt tcp_swnd tcp_mss

  8e176ce4 f8dc 5b4

  30000cc2238: tcp_iss tcp_rnxt tcp_rwnd

  8e0b7707 3d49ecf0 60f4

  30000cc2248: tcpb_reflock

  30000cc2248: owner/waiters

  0

  30000cc2250: tcp_refcnt tcpb_vcf tcpb_hops

  1 3c000000 3c

  30000cc225c: tcpb_remote_v6

  30000cc225c: 0 0 ffff c0a80508

  30000cc226c: tcpb_bound_source_v6

  30000cc226c: 0 0 0 0

  30000cc227c: tcpb_ip_src_v6

  30000cc227c: 0 0 ffff c0a80582

  30000cc228c: tcpu_fport tcpu_lport ipsec_out

  1205 17 0

  30000cc2298: ipsec_req_in tcpb_tcp tcpb_ipversion

  0 30000bb6fd0 4

  30000cc22ac: bound_if ownerid

  0 0

  $q

  #

  于是我们可以写这样一个脚本kill_timewait.sh

  --------------------------------------------------------------------------

  #! /sbin/sh

  #

  #

  # @(#)kill_timewait.sh 2002-07-07 NSFocus Copyleft 2002-2012

  #

  # Notice here is copyleft but not copyright, enjoy it by yourself.

  #

  # ------------------------------------------------------------------------

  # File : kill_timewait.sh

  # Platform : SPARC/Solaris 8 64-bit kernel mode

  # Author : NSFocus Security Team

  # :

  # Date : 2002-07-07 12:27

  # Modify :

  # Thanks :cdjohns@nswc-g.arpa for SunOS 4.x implementation

  #

  netstat -na -P tcp -f inet | grep TIME_WAIT

  echo

  echo 'TCPB dest [lport,fport] state'

  echo

  ndd /dev/tcp tcp_status | nawk '{print $1 " " $2 " " $16 $17 " " $18}' | egrep 'TIME_WAIT'

  echo

  /usr/bin/echo 'TCPB address to terminate: \c'

  read tcpb_addr

  echo

  adb -k /dev/ksyms /dev/mem << NSFOCUS_EOF

  $tcpb_addr$

  $q

  NSFOCUS_EOF

  #

  # Check to see if this was the correct address and TCPB. state should be 6

  #

  echo

  echo 'tcp_state = 6 = TCPS_TIME_WAIT'

  /usr/bin/echo 'Is this the correct TCPB (y/n)? \c'

  read answer

  echo

  case $answer in

  [Yy]*)

  ;;

  *)

  echo 'No Changes.'

  exit

  ;;

  esac

  #

  # Kernel Hacking, please. These value are expressed in hexadecimal.

  #

  TIME_WAIT_EXPIRE_OFFSET=0x30

  STATE_OFFSET=0x40

  #

  # This value is expressed in decimal and must be greater than zero.

  #

  TIME_WAIT_EXPIRE=0t06

  #

  # Use adb on kernel to set the tcpb_time_wait_expire=6 and

  # tcpb_state=TCPS_CLOSED (-6)

  #

  adb -kw /dev/ksyms /dev/mem << NSFOCUS_EOF

  $tcpb_addr+$TIME_WAIT_EXPIRE_OFFSET/Z $TIME_WAIT_EXPIRE

  $tcpb_addr+$STATE_OFFSET/W -6

  $q

  NSFOCUS_EOF

  echo

  echo "TIME_WAIT state will disappear."

  echo

  netstat -na -P tcp -f inet | grep TIME_WAIT

  --------------------------------------------------------------------------

  不要设置tcpb_time_wait_expire成零,只要是一个很小的值就可以了。这里必须同

  时设置tcpb_time_wait_expire和tcpb_state,只设置其中一个达不到效果。

  利用adb从TCPS_ESTABLISHED变为TCPS_CLOSE_WAIT,可以使一条TCP连接不再工作,

  但这条连接并未销毁,tcpb_t结构也未删除。

  利用adb从TCPS_ESTABLISHED变为TCPS_CLOSED,会导致整个操作系统崩溃。可能是下

  层tcpb_t结构被删除,而上层socket并不了解,出现非法指针。

  简化一下kill_timewait.sh

  --------------------------------------------------------------------------

  #! /sbin/sh

  ndd /dev/tcp tcp_status | nawk '{print $1 " " $2 " " $16 $17 " " $18}' | egrep 'TIME_WAIT'

  echo

  /usr/bin/echo 'TCPB address to terminate: \c'

  read tcpb_addr

  echo

  adb -kw /dev/ksyms /dev/mem << NSFOCUS_EOF

  $tcpb_addr+0x30/Z 0t6

  $tcpb_addr+0x40/W -6

  $q

  NSFOCUS_EOF

  --------------------------------------------------------------------------

  还可以写一个脚本自动清除所有TIME_WAIT状态TCP连接

  --------------------------------------------------------------------------

  #! /sbin/sh

  ndd /dev/tcp tcp_status | nawk '{print $1 " " $2 " " $16 $17 " " $18}' | \

  egrep 'TIME_WAIT' | cut -d' ' -f1 | while read tcpb_addr

  do

  adb -kw /dev/ksyms /dev/mem << NSFOCUS_EOF

  $tcpb_addr+0x30/Z 0t6

  $tcpb_addr+0x40/W -6

相关推荐
新闻聚焦
猜你喜欢
热门推荐
  • “饭前喝汤,养胃健康”,其实很多人对

      生活水平的改变,现在的饮食文化也开始不在局限,吸收精华,取长补短,经常可以在小区的楼下看到很多的食肆,瓦罐汤更......

    03-19    来源:未知

    分享
  • 戴套八个错,避孕会失败

      男用避孕套是最思空见贯的避孕办法之一,但其避孕失利的情况其实许多见。据统计,若能切确使用质量有担保的避孕套,失败......

    04-09    来源:未知

    分享
  • 理邦仪器涉案专利宣告全部无效

      4月18日晚间,迈瑞医疗(300760.SZ)发布《诉讼搁浅通知布告》,其与理邦仪器(300206.SZ)的专利连累案件也有新停留。 公然......

    04-20    来源:未知

    分享
  • 哪个年龄段更好

      对付如今这个快节奏生存来说,不论是在糊口生涯还是任务上,每小我私家都具备着极大的压力。因而良多人城市出现失眠以......

    05-05    来源:未知

    分享
  • 一套“开髋&伸展双腿”的阴瑜伽序列

      对阴瑜伽有所了解的伽人们都知道,阴瑜伽主要注重身体髋、骨盆以及双腿下半身的练习,所以想要打开髋部以及伸展双腿,......

    05-15    来源:未知

    分享
  • 热点 “英雄小八路”进校园

      焦炙焦虑感可以在一天中的任什么时分候袭来,但它最多见于早上刚醒来时。针对醒来后的焦炙,美国西北大学的临床生理学......

    07-05    来源:未知

    分享
  • 头条 辛识平:谎言在事实面前总是不攻自

      面临媒体与人民,美方一些人一会是这个说法,一会又是另外一套解释,让不少东方传媒觉得难以捉摸。美方一些酬劳什么老......

    08-28    来源:未知

    分享
  • 人文 网络招聘及交友平台签自律公约

      原题目:网络应聘及交友平台签自律合同 《互联网招聘行业自律合同》与《互联网婚恋结交行业自律合同》克期正式揭晓,......

    10-25    来源:未知

    分享
  • 最新 浪潮发布数字化中台 为百万家企业

      原标题:浪潮公布数字化中台 为百万家企业供给数字化转型效力 第六届互联网之光博览会20日至22日举行。海潮在会上颁布发......

    10-25    来源:未知

    分享
  • 扁桃体发炎吃什么最好

      1、扁桃体发炎吃什么最好之金橘 金橘是一种缓解扁桃体发炎的好水果,因为金橘中含有碱性的物质,还带有一点点的甜味,很多......

    05-13    来源:未知

    分享
返回列表
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。