TCPConnectionUtility.py 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. import random
  2. import socket
  3. import threading
  4. from NativeLog import NativeLog
  5. # from NativeLog import NativeLog
  6. # make sure target do not listen on this port
  7. ERROR_PORT = 62685
  8. class Utility(object):
  9. METHOD_RESULT = {"C_01": ("ESTABLISHED", "ESTABLISHED"), # target TCP peer state, PC TCP peer state
  10. "C_02": ("SYNC_SENT", "CLOSED"),
  11. "C_03": ("CLOSED", "CLOSED"),
  12. "C_04": ("SYN_RCVD", "ESTABLISHED"),
  13. "C_05": ("ESTABLISHED", "ESTABLISHED"),
  14. "C_06": ("CLOSED", "CLOSED"),
  15. "C_07": ("CLOSED", "CLOSED"),
  16. "C_08": ("CLOSED", "CLOSED"),
  17. "D_01": ("TIME_WAIT", "CLOSED"),
  18. "D_02": ("TIME_WAIT", "TIME_WAIT"),
  19. "D_03": ("FIN_WAIT_2", "CLOSE_WAIT"),
  20. "D_04": ("FIN_WAIT_1", "CLOSE_WAIT"),
  21. "D_05": ("CLOSED", "TIME_WAIT"),
  22. "D_06": ("CLOSED", "CLOSED"),
  23. "D_07": ("CLOSE_WAIT", "FIN_WAIT2"),
  24. "D_08": ("TIME_WAIT", "CLOSED"), }
  25. SOC_CLOSED_STATE = ("FIN_WAIT_1", "FIN_WAIT_2", "CLOSING", "TIME_WAIT", "LAST_ACK", "CLOSED")
  26. SOC_CREATED_STATE = ("SYNC_RCVD", "ESTABLISHED")
  27. SOC_SEND_DATA_STATE = ("ESTABLISHED", "CLOSE_WAIT")
  28. SOC_ESTABLISHED_STATE = ("ESTABLISHED", )
  29. def __init__(self, tc_action, pc_server_port, target_server_port, pc_ip, target_ip):
  30. self.tc_action = tc_action
  31. self.pc_server_port = pc_server_port
  32. self.target_server_port = target_server_port
  33. self.pc_ip = pc_ip
  34. self.target_ip = target_ip
  35. self.pc_close_wait_socket_list = []
  36. self.sync_lock = threading.Lock()
  37. pass
  38. # create a tcp socket, return True or False
  39. def __create_tcp_socket(self, connection):
  40. connection_handler = connection["Connection handler"]
  41. connection["Target port"] = random.randint(10000, 60000)
  42. connection_handler.add_checkers("BIND:(\d+),OK,%s,%s"
  43. % (self.target_ip, connection["Target port"]))
  44. self.tc_action.send_ssc_command("soc -B -t TCP -i %s -p %s" % (self.target_ip, connection["Target port"]))
  45. serial_result, tcp_result = connection_handler.get_checker_results()
  46. if serial_result is not None:
  47. connection["Target socket id"] = serial_result.group(1)
  48. return True
  49. else:
  50. return False
  51. # target do connect, return True or False
  52. def __target_do_connect(self, connection, dest_ip, dest_port, timeout=20):
  53. connection_handler = connection["Connection handler"]
  54. connection_handler.add_checkers("CONNECT:%s,OK" % connection["Target socket id"],
  55. connection["Target port"])
  56. self.tc_action.send_ssc_command("soc -C -s %s -i %s -p %s"
  57. % (connection["Target socket id"], dest_ip, dest_port))
  58. serial_result, tcp_result = connection_handler.get_checker_results(timeout)
  59. if serial_result is not None and tcp_result is not None:
  60. connection["PC socket"] = tcp_result
  61. return True
  62. else:
  63. return False
  64. pass
  65. # pc do connect, return True or False
  66. def __pc_do_connect(self, connection, dest_ip, dest_port, timeout=20):
  67. connection_handler = connection["Connection handler"]
  68. sock = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
  69. while True:
  70. connection["PC port"] = random.randint(10000, 60000)
  71. try:
  72. sock.bind((self.pc_ip, connection["PC port"]))
  73. break
  74. except socket.error, e:
  75. if e.errno == 10048: # socket port reuse
  76. continue
  77. sock.settimeout(timeout)
  78. connection["PC socket"] = sock
  79. connection_handler.add_checkers("ACCEPT:(\d+),\d+,%s,%s"
  80. % (self.pc_ip, connection["PC port"]))
  81. try:
  82. sock.connect((dest_ip, dest_port))
  83. except socket.error:
  84. pass
  85. serial_result, tcp_result = connection_handler.get_checker_results()
  86. if serial_result is not None:
  87. connection["Target socket id"] = serial_result.group(1)
  88. return True
  89. else:
  90. return False
  91. pass
  92. def connect_c_01(self, connection):
  93. if self.__create_tcp_socket(connection) is True:
  94. return self.__target_do_connect(connection, self.pc_ip, self.pc_server_port)
  95. else:
  96. return False
  97. def connect_c_02(self, connection):
  98. if self.__create_tcp_socket(connection) is True:
  99. return not self.__target_do_connect(connection, self.pc_ip, ERROR_PORT, timeout=5)
  100. else:
  101. return False
  102. def connect_c_03(self, connection):
  103. return False
  104. def connect_c_04(self, connection):
  105. return False
  106. def connect_c_05(self, connection):
  107. return self.__pc_do_connect(connection, self.target_ip, self.target_server_port)
  108. def connect_c_06(self, connection):
  109. return False
  110. def connect_c_07(self, connection):
  111. return not self.__pc_do_connect(connection, self.target_ip, ERROR_PORT)
  112. def connect_c_08(self, connection):
  113. return False
  114. def __target_socket_close(self, connection):
  115. connection_handler = connection["Connection handler"]
  116. if connection["Target socket id"] is not None:
  117. connection_handler.add_checkers("CLOSE:%s" % connection["Target socket id"])
  118. self.tc_action.send_ssc_command("soc -T -s %s" % connection["Target socket id"])
  119. serial_result, tcp_result = connection_handler.get_checker_results()
  120. connection["Target socket id"] = None
  121. else:
  122. serial_result = None
  123. return True if serial_result is not None else False
  124. @staticmethod
  125. def __pc_socket_close(connection):
  126. connection_handler = connection["Connection handler"]
  127. if connection["PC socket"] is not None:
  128. connection_handler.add_checkers("CLOSED:%s" % connection["Target socket id"])
  129. connection["PC socket"].close()
  130. serial_result, tcp_result = connection_handler.get_checker_results()
  131. connection["PC socket"] = None
  132. else:
  133. serial_result = None
  134. return True if serial_result is not None else False
  135. def close_d_01(self, connection):
  136. connection["PC socket"] = None
  137. return self.__target_socket_close(connection)
  138. def close_d_02(self, connection):
  139. pass
  140. def close_d_03(self, connection):
  141. with self.sync_lock:
  142. self.pc_close_wait_socket_list.append(connection["PC socket"])
  143. return self.__target_socket_close(connection)
  144. pass
  145. def close_d_04(self, connection):
  146. pass
  147. def close_d_05(self, connection):
  148. return self.__pc_socket_close(connection)
  149. def close_d_06(self, connection):
  150. # target send data to PC, PC don't recv and close socket
  151. connection_handler = connection["Connection handler"]
  152. connection_handler.add_checkers("SEND:%s,OK" % connection["Target socket id"])
  153. self.tc_action.send_ssc_command("soc -S -s %s -l 100" % connection["Target socket id"])
  154. serial_result, tcp_result = connection_handler.get_checker_results()
  155. if serial_result is None:
  156. return False
  157. return self.__pc_socket_close(connection)
  158. def close_d_07(self, connection):
  159. # PC shutdown WR
  160. result = False
  161. try:
  162. connection["PC socket"].shutdown(socket.SHUT_WR)
  163. result = True
  164. except StandardError:
  165. pass
  166. return result
  167. def close_d_08(self, connection):
  168. pass
  169. def close_connection(self, connection):
  170. self.__target_socket_close(connection)
  171. pass
  172. TCP_ACTION_DICT = {"C_01": connect_c_01,
  173. "C_02": connect_c_02,
  174. "C_03": connect_c_03,
  175. "C_04": connect_c_04,
  176. "C_05": connect_c_05,
  177. "C_06": connect_c_06,
  178. "C_07": connect_c_07,
  179. "C_08": connect_c_08,
  180. "D_01": close_d_01,
  181. "D_02": close_d_02,
  182. "D_03": close_d_03,
  183. "D_04": close_d_04,
  184. "D_05": close_d_05,
  185. "D_06": close_d_06,
  186. "D_07": close_d_07,
  187. "D_08": close_d_08,
  188. }
  189. def get_method_destination_state(self, method):
  190. return self.METHOD_RESULT[method]
  191. def execute_tcp_method(self, method, connection):
  192. if method in self.METHOD_RESULT:
  193. result = self.TCP_ACTION_DICT[method](self, connection)
  194. if result is True:
  195. state = self.get_method_destination_state(method)
  196. connection["Target state"] = state[0]
  197. connection["PC state"] = state[1]
  198. else:
  199. NativeLog.add_prompt_trace("[TCPConnection] tcp method %s fail, connection is %s"
  200. % (method, connection))
  201. NativeLog.add_trace_info("[TCPConnection][data cache][check item %s] %s"
  202. % (connection["Connection handler"].serial_check_item_id,
  203. connection["Connection handler"].data_cache))
  204. else:
  205. raise StandardError("Not TCP connection method")
  206. return result
  207. def is_established_state(self, connection):
  208. return True if connection["Target state"] in self.SOC_CREATED_STATE else False
  209. def is_closed_state(self, connection):
  210. return True if connection["Target state"] in self.SOC_CLOSED_STATE else False
  211. def main():
  212. pass
  213. if __name__ == '__main__':
  214. main()