PageRenderTime 85ms CodeModel.GetById 29ms RepoModel.GetById 1ms app.codeStats 0ms

/client/src/com/mobiperf/PortScan.java

https://github.com/quietbamboo/MobiPerfUmich
Java | 328 lines | 209 code | 61 blank | 58 comment | 33 complexity | 381be1a149d9b971821684e7904eb519 MD5 | raw file
  1. /****************************
  2. * This file is part of the MobiPerf project (http://mobiperf.com).
  3. * We make it open source to help the research community share our efforts.
  4. * If you want to use all or part of this project, please give us credit and cite MobiPerf's official website (mobiperf.com).
  5. * The package is distributed under license GPLv3.
  6. * If you have any feedbacks or suggestions, don't hesitate to send us emails (3gtest@umich.edu).
  7. * The server suite source code is not included in this package, if you have specific questions related with servers, please also send us emails
  8. *
  9. * Contact: 3gtest@umich.edu
  10. * Development Team: Junxian Huang, Birjodh Tiwana, Zhaoguang Wang, Zhiyun Qian, Cheng Chen, Yutong Pei, Feng Qian, Qiang Xu
  11. * Copyright: RobustNet Research Group led by Professor Z. Morley Mao, (Department of EECS, University of Michigan, Ann Arbor) and Microsoft Research
  12. *
  13. ****************************/
  14. package com.mobiperf;
  15. import java.io.DataInputStream;
  16. import java.io.DataOutputStream;
  17. import java.net.DatagramPacket;
  18. import java.net.DatagramSocket;
  19. import java.net.InetAddress;
  20. import java.net.InetSocketAddress;
  21. import java.net.Socket;
  22. import java.net.SocketAddress;
  23. import java.util.Random;
  24. import android.util.Log;
  25. public class PortScan extends Thread {
  26. public static final int DIRECTION_UP = 1;
  27. public static final int DIRECTION_DOWN = 2;
  28. public static final int DIRECTION_BOTH = 3;
  29. public static final String[] DIRECTION_TAGS = new String[]{"DR:DEFAULT", "DR:UP", "DR:DOWN", "DR:BOTH"};
  30. private int index;
  31. public static int activeTest = 0;
  32. //Reachability test shared variables
  33. public static int finishedPorts = 0;
  34. public static boolean[] reachable = new boolean[Definition.PORTS.length];
  35. public static char[] blockedStage = new char[Definition.PORTS.length]; //'c' for connect, 'd' for data
  36. /**
  37. *
  38. * @param index
  39. * @param serverIP
  40. * @param longTest if true, it is a complete test rather than simple testing blocking
  41. * (for local use only or FCC)
  42. */
  43. public PortScan(int index){
  44. this.index = index;
  45. }
  46. public void run(){
  47. //basic 3GTest reachability test
  48. shortTest();
  49. }
  50. /**
  51. *
  52. * @param PACKET_SIZE specify total packet size including IP TCP/UDP headers
  53. * minimum packet size set to 100 bytes > (20 + 32 + 18 + 13)
  54. * @param NUM_EXP number of experiments
  55. * @param DIRECTION 1 uplink, 2 downlink, 3 both direction
  56. * For uplink, send PACKET_SIZE to server and server will respond with 1 byte, vice versa for downlink
  57. */
  58. public void rttWithPacketSize(int PACKET_SIZE, int NUM_EXP, int DIRECTION){
  59. int ACTUAL_PACKET_SIZE = PACKET_SIZE; //packet size to be sent
  60. int ORIGINAL_PACKET_SIZE = PACKET_SIZE;//packet size of this experiment, only larger than actual when downlink
  61. int port = Definition.PORTS[index];
  62. if(DIRECTION == PortScan.DIRECTION_DOWN){
  63. //if downlink, only send comment to server, in the command, original PACKET_SIZE is already written
  64. ACTUAL_PACKET_SIZE = 100;
  65. }
  66. //DR:UP__SIZE:100__randomstuff
  67. String payload = DIRECTION_TAGS[DIRECTION] + "__SIZE:" + ORIGINAL_PACKET_SIZE + "__";
  68. Random ran = new Random();
  69. while(payload.length() < ACTUAL_PACKET_SIZE){
  70. payload += ran.nextDouble();
  71. payload += ran.nextLong();
  72. payload += ran.nextFloat();
  73. }
  74. if(ACTUAL_PACKET_SIZE < payload.length())
  75. payload = payload.substring(0, ACTUAL_PACKET_SIZE);//will cut later depending on packet type
  76. //Log.v("MobiOpen", "rubbish length " + rubbish.length());
  77. //Log.v("MobiOpen", "PACKET_SIZE " + ORIGINAL_PACKET_SIZE + " NUM_EXP " + NUM_EXP +
  78. // " payload length " + payload.length());
  79. long start, end;
  80. try {
  81. warmUpWithUdp();
  82. String result = "";
  83. //NUM_EXP TCP experiments
  84. for(int i = 0 ; i < NUM_EXP ; i++){
  85. //promote to DCH
  86. if(i % 5 == 0)
  87. warmUpWithUdp();
  88. Socket tcpSocket = new Socket();
  89. tcpSocket.setSoTimeout(Definition.TCP_TIMEOUT_IN_MILLI);
  90. SocketAddress remoteAddr = new InetSocketAddress(Definition.SERVER_NAME, port);
  91. DataOutputStream os = null;
  92. DataInputStream is = null;
  93. //measure latency of establishing TCP connection, is it RTT?
  94. //validated by trace
  95. byte[] buf = (payload.substring(0, ACTUAL_PACKET_SIZE -
  96. Definition.IP_HEADER_LENGTH - Definition.TCP_HEADER_LENGTH -
  97. ("" + System.currentTimeMillis()).length()) +
  98. System.currentTimeMillis()).getBytes();
  99. byte[] recv_buf = new byte[ORIGINAL_PACKET_SIZE];
  100. start = System.currentTimeMillis();
  101. try{
  102. tcpSocket.connect( remoteAddr, Definition.TCP_TIMEOUT_IN_MILLI );
  103. }catch ( Exception e ) {
  104. }
  105. //test connect time
  106. end = System.currentTimeMillis();
  107. Log.v("MobiOpen", "CONNECT port " + port +
  108. " run " + i + " res " + (end - start) + " " + DIRECTION_TAGS[DIRECTION]);
  109. result += "MobiOpen:CONNECT port " + port + " sequence " + i + " delay " + (end - start) +
  110. " timestamp " + System.currentTimeMillis() +
  111. " packet_size " + ORIGINAL_PACKET_SIZE + " " + DIRECTION_TAGS[DIRECTION] + "\n";
  112. //speed up timeout experiments
  113. if((end - start) > 3000){
  114. NUM_EXP -= 3;
  115. continue;
  116. }
  117. //ignore HTTP SSH HTTPS
  118. if(port != 80 && port != 22 && port != 443){
  119. try{
  120. os = new DataOutputStream( tcpSocket.getOutputStream() );
  121. is = new DataInputStream( tcpSocket.getInputStream() );
  122. //restart timer
  123. start = System.currentTimeMillis();
  124. os.write(buf);
  125. os.flush();
  126. is.read(recv_buf, 0, recv_buf.length);
  127. }catch ( Exception e ) {
  128. }
  129. //end time for both timeout and normal execution
  130. end = System.currentTimeMillis();
  131. Log.v("MobiOpen", "TCP port " + port +
  132. " run " + i + " res " + (end - start) + " " + DIRECTION_TAGS[DIRECTION]);
  133. result += "MobiOpen:TCP port " + port + " sequence " + i + " delay " + (end - start) +
  134. " timestamp " + System.currentTimeMillis() +
  135. " packet_size " + ORIGINAL_PACKET_SIZE + " " + DIRECTION_TAGS[DIRECTION] + "\n";
  136. if(is != null)
  137. is.close();
  138. if(os != null)
  139. os.close();
  140. }
  141. tcpSocket.close();
  142. }
  143. //NUM_EXP UDP experiments
  144. for(int i = 0 ; i < NUM_EXP ; i++){
  145. //promote to DCH
  146. if(i % 5 == 0)
  147. warmUpWithUdp();
  148. DatagramSocket socket = new DatagramSocket();
  149. byte[] buf = (payload.substring(0, ACTUAL_PACKET_SIZE -
  150. Definition.IP_HEADER_LENGTH - Definition.UDP_HEADER_LENGTH -
  151. ("" + System.currentTimeMillis()).length()) +
  152. System.currentTimeMillis()).getBytes();
  153. InetAddress address = InetAddress.getByName(Definition.SERVER_NAME);//should this be IP? no..
  154. DatagramPacket packet = new DatagramPacket(buf, buf.length, address, port);
  155. socket.setSoTimeout(Definition.TCP_TIMEOUT_IN_MILLI);
  156. //prepare to receive request
  157. byte[] buf2 = new byte[ORIGINAL_PACKET_SIZE];
  158. DatagramPacket p2 = new DatagramPacket(buf2, buf2.length);
  159. //send
  160. start = System.currentTimeMillis();
  161. socket.send(packet);
  162. //receive
  163. try{
  164. socket.receive(p2);
  165. }catch ( Exception e ) {
  166. }
  167. end = System.currentTimeMillis();
  168. Log.v("MobiOpen", "UDP port " + port +
  169. " run " + i + " res " + (end - start) + " " + DIRECTION_TAGS[DIRECTION]);
  170. result += "MobiOpen:UDP port " + port + " sequence " + i + " delay " + (end - start) +
  171. " timestamp " + System.currentTimeMillis() +
  172. " packet_size " + ORIGINAL_PACKET_SIZE + " " + DIRECTION_TAGS[DIRECTION] + "\n";
  173. socket.close();
  174. }
  175. (new Report()).sendReport(result);
  176. }
  177. catch ( Exception e ) {
  178. e.printStackTrace();
  179. }
  180. //let server thread know that it is done
  181. //MainThread.rPorts++;
  182. }
  183. public void warmUpWithUdp(){
  184. try {
  185. int index = 5; //this is not blocked by t-mobile
  186. String rubbish = "RUBBISH:";
  187. Random ran = new Random();
  188. while(rubbish.length() < 2000){
  189. rubbish += ran.nextDouble();
  190. rubbish += ran.nextLong();
  191. rubbish += ran.nextFloat();
  192. rubbish += "hellorubbish";
  193. }
  194. DatagramSocket socket = new DatagramSocket();
  195. byte[] buf = rubbish.getBytes();
  196. InetAddress address = InetAddress.getByName(Definition.SERVER_NAME);//should this be IP? no..
  197. DatagramPacket packet = new DatagramPacket(buf, buf.length, address, Definition.PORTS[index]);
  198. socket.setSoTimeout(Definition.TCP_TIMEOUT_IN_MILLI);
  199. //prepare to receive request
  200. byte[] buf2 = new byte[10000];
  201. DatagramPacket p2 = new DatagramPacket(buf2, buf2.length);
  202. //send
  203. socket.send(packet);
  204. //receive
  205. socket.receive(p2);
  206. socket.close();
  207. } catch (Exception e) {
  208. e.printStackTrace();
  209. }
  210. }
  211. public void shortTest(){
  212. reachable[index] = false;
  213. blockedStage[index] = 'o';
  214. Socket tcpSocket = null;
  215. DataOutputStream os = null;
  216. DataInputStream is = null;
  217. try {
  218. tcpSocket = new Socket();
  219. SocketAddress remoteAddr = new InetSocketAddress(Definition.SERVER_NAME, Definition.PORTS[index] );
  220. tcpSocket.connect( remoteAddr, Definition.TCP_TIMEOUT_IN_MILLI );
  221. os = new DataOutputStream( tcpSocket.getOutputStream() );
  222. is = new DataInputStream( tcpSocket.getInputStream() );
  223. tcpSocket.setSoTimeout( Definition.TCP_TIMEOUT_IN_MILLI );
  224. }catch ( Exception e ) {
  225. e.printStackTrace();
  226. blockedStage[ index ] = 'c';
  227. }
  228. if ( tcpSocket == null || os == null || is == null )
  229. blockedStage[ index ] = 'c';
  230. else{
  231. try {
  232. String helloString = "hello" + System.currentTimeMillis() + Definition.PORTS[index];
  233. byte [] message = helloString.getBytes();
  234. os.write(message);
  235. os.flush();
  236. byte[] buffer = new byte[ 1000 ];
  237. int read_bytes = is.read( buffer, 0, 1000 );
  238. if ( read_bytes != -1 ) {
  239. String reply = new String( buffer, 0, read_bytes );
  240. Log.v("LOG", "in port scanning " + index + " for port " + Definition.PORTS[index] +
  241. " the reply message we got is <" + reply + ">, length: " + read_bytes);
  242. if(reply.equals(helloString)) {
  243. //Log.v("LOG", "it is the same as hello");
  244. reachable[ index ] = true;
  245. }
  246. else if(Definition.PORTS[index] == 22 && reply.startsWith("SSH")) {
  247. reachable[ index ] = true;
  248. //need to process HTTPS, HTTP here
  249. }else{
  250. //Log.v("LOG", "it is different");
  251. blockedStage[ index ] = 'd';
  252. }
  253. }else{
  254. blockedStage[ index ] = 'd';
  255. }
  256. os.close();
  257. is.close();
  258. tcpSocket.close();
  259. }catch ( Exception e ) {
  260. blockedStage[ index ] = 'd';
  261. e.printStackTrace();
  262. }
  263. }
  264. //let server thread know that it is done
  265. finishedPorts++;
  266. }
  267. }