1
10package org.jstk.ssl;
11
12
13import java.io.*;
14import java.util.HashMap;
15import java.net.*;
16import javax.net.SocketFactory;
17import javax.net.ssl.SSLSocketFactory;
18import javax.net.ssl.SSLSession;
19import javax.net.ssl.SSLSocket;
20import javax.net.ssl.HttpsURLConnection;
21import javax.net.ssl.HostnameVerifier;
22import org.jstk.*;
23
24public class ClientCommand extends JSTKCommandAdapter {
25 public class ReaderThread extends Thread {
26 private JSTKSocket socket;
27 private JSTKBuffer buf;
28 public ReaderThread(JSTKSocket socket, JSTKBuffer buf){
29 super("ReaderThread");
30 this.socket = socket;
31 this.buf = buf;
32 }
33
34 public void run() {
35 try {
36 int n;
37 while ((n = socket.read(buf)) != -1);
38 } catch (Exception e) { }
39 }
40 }
41
42 public class CustomHostnameVerifier implements HostnameVerifier {
43 private String expectedHostname;
44 public CustomHostnameVerifier(String expectedHostname){
45 this.expectedHostname = expectedHostname;
46 }
47 public boolean verify(String hostname, SSLSession sess){
48 System.out.print("Expected: " + expectedHostname + ", Got: " + hostname + ". ");
49 System.out.print("Proceed(yes/no)?");
50 System.out.flush();
51 BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
52 String response = null;
53 try {
54 response = br.readLine();
55 } catch (IOException ioe){
56 response = "no";
57 }
58 if ("yes".equalsIgnoreCase(response.trim()))
59 return true;
60 return false;
61 }
62 }
63
64 private static int outPort = -1;
65 public static int getOutPort(){
66 return outPort;
67 }
68 public static void setOutPort(int port){
69 outPort = port;
70 }
71 private static HashMap defaults = new HashMap();
72 static {
73 defaults.put("host", "localhost");
74 defaults.put("port", "9000");
75 defaults.put("outproto", "TCP");
76 defaults.put("mode", "prompt");
77 defaults.put("bufsize", "8192");
78 defaults.put("num", "2048");
79 defaults.put("action", "write-only");
80 }
81
82 public String briefDescription(){
83 String briefDesc = "simple client for TCP or SSL connections";
84 return briefDesc;
85 }
86
87 public String optionsDescription(){
88 String optionsDesc =
89 " -host <host> : Remote host machine name or IP address.[" +
90 defaults.get("host") + "]\n" +
91 " -port <port> : Destination port on remote host.[" +
92 defaults.get("port") + "]\n" +
93 " -outproto <proto>: Outgoing connection protocol (TCP or SSL).[" +
94 defaults.get("outproto") + "]\n" +
95 " -csfile <csfile>: File having cipher suits to be enabled.\n" +
96 " -mode <mode> : Client operation mode(prompt|bench|read-url).[" +
97 defaults.get("mode") + "]\n" +
98 " -action <action>: What action to take -- applicable for \"bench\" mode\n" +
99 " (open-close|write-only|write-read|read-url).[" +
00 defaults.get("action") + "]\n" +
01 " -bufsize <size> : len. of buf (for bench mode).[" +
02 defaults.get("bufsize") + "]\n" +
03 " -num <num> : no. of times buf is written/read(for bench mode).[" +
04 defaults.get("num") + "]\n" +
05 " -url <httpurl> : URL to be read (for bench/read-url or read-url).\n" +
06 " -pattern <pat> : Fill buffer with this pattern(for bench mode).\n" +
07 " -verbose : Verbose output.\n" +
08 " -conn close : Close connection with every read-url action.\n" +
09 " -inetaddr <addr>: Network IP address (useful for multi-homed hosts).\n";
10 return optionsDesc;
11 }
12 public String[] useForms(){
13 String[] useForms = {
14 "[-host <host>] [-port <port>] [-ssl] [-inetaddr <addr>]"
15 };
16 return useForms;
17 }
18 public String[] sampleUses(){
19 String[] sampleUses = {
20 "",
21 "-host venus -port 2950",
22 "-ssl"
23 };
24 return sampleUses;
25 }
26
27 private JSTKResult runRMIClient(JSTKArgs args) throws Exception{
28 int bufsize = Integer.parseInt(args.get("bufsize"));
29 int num = Integer.parseInt(args.get("num"));
30 int port = Integer.parseInt(args.get("port"));
31 String mode = args.get("mode");
32 String action = args.get("action");
33 boolean verbose = Boolean.valueOf(args.get("verbose")).booleanValue();
34 String pattern = args.get("pattern");
35 String host = args.get("host");
36
37 setOutPort(port);
38 RMIServerInterface obj = null;
39 String url = "//" + host + "/RMIServer";
40 try {
41 obj = (RMIServerInterface)java.rmi.Naming.lookup(url);
42 } catch (Exception exc){
43 return new JSTKResult(null, false, "Failed to lookup \"" + url + "\": " + exc);
44 }
45
46 if (mode.equalsIgnoreCase("bench")){
47 int numBytes = 0;
48 byte[] buf = new byte[bufsize];
49 if (action.equalsIgnoreCase("write-only")){
50 long st = System.currentTimeMillis();
51 for (int i = 0; i < num; i++){
52 obj.writeOnly(buf);
53 if (verbose)
54 System.out.println("[" + i + "]Wrote: " + buf.length + " bytes.");
55 numBytes += buf.length;
56 }
57 long et = System.currentTimeMillis();
58 double writeRate = ((double)numBytes*1000.0)/(et - st);
59 double tt = (et - st)/1000.0;
60
61 System.out.print("Invoked RMI method " + num + " times in " + tt + " seconds.\n");
62 System.out.println(" Write Rate: " + writeRate + " bytes/sec.");
63 } else if (action.equalsIgnoreCase("write-read")){
64 int numRead = 0;
65 long st = System.currentTimeMillis();
66 for (int i = 0; i < num; i++){
67 byte[] tbuf = obj.writeRead(buf);
68 if (verbose)
69 System.out.println("[" + i + "]Wrote: " + buf.length +
70 " bytes, Read: " + tbuf.length + " bytes.");
71 numBytes += buf.length;
72 numRead += tbuf.length;
73 }
74 long et = System.currentTimeMillis();
75 double writeRate = ((double)numBytes*1000.0)/(et - st);
76 double readRate = ((double)numRead*1000.0)/(et - st);
77 double tt = (et - st)/1000.0;
78
79 System.out.print("Invoked RMI method " + num + " times in " + tt + " seconds.\n");
80 System.out.println(" Write Rate: " + writeRate + " bytes/sec.");
81 System.out.println(" Read Rate : " + readRate + " bytes/sec.");
82 } else {
83 return new JSTKResult(null, true, "Unknown action: " + action);
84 }
85 } else if (mode.equalsIgnoreCase("prompt")){
86 BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
87 while (true){
88 System.out.print("Enter Message: ");
89 System.out.flush();
90 String inp = br.readLine();
91 if (inp.equalsIgnoreCase("quit"))
92 break;
93 byte[] tbuf = obj.writeRead(inp.getBytes());
94 System.out.println("Server Returned: " + new String(tbuf));
95 }
96 } else {
97 return new JSTKResult(null, true, "Unknown mode: " + mode);
98 }
99 return new JSTKResult(null, true, "DONE");
00 }
01
02 private JSTKResult processReadURL(JSTKArgs args, int num,
03 int bufsize, String mode, boolean verbose) throws IOException {
04 boolean connClose = false;
05 String urlString = args.get("url");
06 String connString = args.get("conn");
07 if (connString != null && connString.equalsIgnoreCase("close"))
08 connClose = true;
09 if (urlString == null)
10 return new JSTKResult(null, false, "No URL specified");
11
12 System.out.println(" URL : " + urlString);
13
14 URL url = new URL(urlString);
15 CustomHostnameVerifier custVerifier = new CustomHostnameVerifier(url.getHost());
16 HttpsURLConnection.setDefaultHostnameVerifier(custVerifier);
17 if (mode.equalsIgnoreCase("bench")){
18 long st = System.currentTimeMillis();
19 int numBytes = 0;
20 byte[] buf = new byte[bufsize];
21 for (int i = 0; i < num; i++){
22 HttpURLConnection urlCon = (HttpURLConnection)url.openConnection();
23 BufferedInputStream bis = new BufferedInputStream(urlCon.getInputStream());
24 int n;
25 int nread = 0;
26 while ((n = bis.read(buf)) != -1){
27 nread += n;
28 }
29 if (verbose){
30 System.out.println("[" + i + "]Read: " + nread + " bytes from: " + urlString);
31 }
32 numBytes += nread;
33 if (connClose)
34 urlCon.disconnect();
35 }
36 long et = System.currentTimeMillis();
37 double browseRate = ((double)numBytes*1000.0)/(et - st);
38 double tt = (et - st)/1000.0;
39
40 System.out.print("Read URL " + urlString + " " + num + " times in " + tt + " seconds.\n");
41 System.out.println(" Browse Rate: " + browseRate + " bytes/sec.");
42 } else {
43 BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
44 String line;
45 while ((line = br.readLine()) != null){
46 System.out.println(line);
47 }
48 }
49 return new JSTKResult(null, true, "DONE");
50 }
51
52 private JSTKResult runTCPClient(JSTKArgs args) throws Exception{
53 String host = args.get("host");
54 int port = Integer.parseInt(args.get("port"));
55 int bufsize = Integer.parseInt(args.get("bufsize"));
56 int num = Integer.parseInt(args.get("num"));
57 String inetAddrVal = args.get("inetaddr");
58 String mode = args.get("mode");
59 String action = args.get("action");
60 boolean verbose = Boolean.valueOf(args.get("verbose")).booleanValue();
61 String pattern = args.get("pattern");
62 String outproto = args.get("outproto");
63
64 System.out.println(" I/O library : " + JSTKSocketUtil.getIOLibrary(args, outproto));
65 System.out.println(" Remote Host : " + host + ", Remote Port: " + port);
66 System.out.println(" -----------------------------------");
67
68 JSTKSocket socket = JSTKSocketUtil.connect(args);
69 JSTKSocketUtil.print(socket, " --> ");
70 if (mode.equalsIgnoreCase("prompt")){
71 BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
72 JSTKBuffer buf = JSTKBuffer.getInstance(bufsize, args);
74 while (true){
75 System.out.print("Enter Message: ");
76 System.out.flush();
77 String inp = br.readLine();
78 if (inp.equalsIgnoreCase("quit"))
79 break;
80 buf.clear();
81 buf.putBytes(inp.getBytes());
82 socket.write(buf);
83 int n = socket.read(buf);
84 System.out.println("Server Returned: " + new String(buf.getBytes()));
85 }
86 socket.close();
87 } else if (mode.equalsIgnoreCase("bench")){
88 JSTKBuffer buf = JSTKBuffer.getInstance(bufsize, args);
89 JSTKBuffer buf1 = JSTKBuffer.getInstance(bufsize, args);
90 (new PatternUtil("00000000")).fillPattern(buf);
91
92 PatternUtil pu = new PatternUtil(pattern);
93
94 long numBytes = 0;
95 if (action.equalsIgnoreCase("write-only")){
96 long st = System.currentTimeMillis();
97 for (int i = 0; i < num; i++){
98 if (pu.needToFill())
99 pu.fillPattern(buf);
00 socket.write(buf);
01 numBytes += buf.getNBytes();
02 if (verbose){
03 System.out.println("[" + i + "]Wrote: " + buf.length() + " bytes.");
04 }
05 }
06 long et = System.currentTimeMillis();
07 socket.close();
08 double xferRate = (double)(numBytes/(et - st)) *(1000.0/1024.0);
09 double tt = (et - st)/1000.0;
10
11 System.out.print("Sent " + numBytes + " bytes in " + tt + " seconds.\n");
12 System.out.println(" 1-way Xfer Rate: " + xferRate + " KB/sec.");
13 } else if (action.equalsIgnoreCase("write-read")){
14 int numBytesRead = 0;
15 long st = System.currentTimeMillis();
16 for (int i = 0; i < num; i++){
17 if (pu.needToFill())
18 pu.fillPattern(buf);
19 socket.write(buf);
20 numBytes += buf.getNBytes();
21 if (verbose){
22 System.out.println("[" + i + "]Sent: " + buf.length() + " bytes.");
23 }
24 int nread = 0;
25 while (nread < bufsize){
26 int n = socket.read(buf);
27 if (n == -1)
28 break;
29 nread += n;
30 }
31 numBytesRead += nread;
32 }
33 long et = System.currentTimeMillis();
34 socket.close();
35 double xferRate = (double)(numBytes/(et - st)) *(1000.0/1024.0);
36 double tt = (et - st)/1000.0;
37
38 System.out.print("Wrote " + numBytes + "and Read " + numBytesRead + " bytes in " + tt + " seconds.\n");
39 System.out.println(" 2-way Xfer Rate: " + xferRate + " KB/sec.");
40 } else if (action.equalsIgnoreCase("open-close")){
41 socket.close(); boolean invalidate = Boolean.valueOf(args.get("invalidate")).booleanValue();
43 long st = System.currentTimeMillis();
44 for (int i = 0; i < num; i++){
45 socket = JSTKSocketUtil.connect(args);
46 if (verbose)
47 System.out.println("[" + i + "]Opened Socket ...");
48
49 if (invalidate && socket.getSocket() instanceof SSLSocket){
50 if (verbose)
51 System.out.println("[" + i + "]Invalidating the SSLSession ...");
52 SSLSocket sslSock = (SSLSocket)socket.getSocket();
53 SSLSession sess = sslSock.getSession();
54 sess.invalidate();
55 }
56
57 socket.close();
58 if (verbose)
59 System.out.println("[" + i + "]Closed Socket ...");
60 }
61 long et = System.currentTimeMillis();
62 double connRate = ((double)num*1000.0)/(et - st);
63 double tt = (et - st)/1000.0;
64
65 System.out.print("" + num + " connections in " + tt + " seconds.\n");
66 System.out.println(" Connection Rate: " + connRate + " connections/sec.");
67 } else if (action.equalsIgnoreCase("read-url")){
68 socket.close(); long st = System.currentTimeMillis();
70 for (int i = 0; i < num; i++){
71 socket = JSTKSocketUtil.connect(args);
72 socket.close();
73 }
74 long et = System.currentTimeMillis();
75 double connRate = ((double)num*1000.0)/(et - st);
76 double tt = (et - st)/1000.0;
77
78 System.out.print("" + num + " connections in " + tt + " seconds.\n");
79 System.out.println(" Connection Rate: " + connRate + " connections/sec.");
80 } else {
81 return new JSTKResult(null, false, "Unknown action: " + action);
82 }
83 } else {
84 return new JSTKResult(null, false, "Unknown mode: " + mode);
85 }
86 return new JSTKResult(null, true, "DONE");
87 }
88
89 private JSTKResult runSSLClient(JSTKArgs args) throws Exception{
90 String[] csarray = JSTKSocketUtil.getCSFileCipherSuites(args);
91 if (csarray != null){
92 System.out.println(" Cipher Suites to be enabled : ");
93 for (int i = 0; i < csarray.length; i++)
94 System.out.println(" " + csarray[i]);
95 }
96 return runTCPClient(args);
97 }
98
99 public Object execute(JSTKArgs args) throws JSTKException{
00 try {
01 args.setDefaults(defaults);
02 String host = args.get("host");
03 int port = Integer.parseInt(args.get("port"));
04 int bufsize = Integer.parseInt(args.get("bufsize"));
05 int num = Integer.parseInt(args.get("num"));
06 String inetAddrVal = args.get("inetaddr");
07 String mode = args.get("mode");
08 String action = args.get("action");
09 boolean verbose = Boolean.valueOf(args.get("verbose")).booleanValue();
10 String pattern = args.get("pattern");
11 String outproto = args.get("outproto");
12 String urlString = args.get("url");
13
14 if (urlString != null){
15 if (urlString.startsWith("https"))
16 outproto = "HTTPS";
17 else if (urlString.startsWith("http"))
18 outproto = "HTTP";
19 else
20 return new JSTKResult(null, false, "Unknown URL format: " + urlString);
21 }
22
23 System.out.println(" Client Mode : " + mode);
24 System.out.println(" OUT protocol : " + outproto);
25
26
27 if (mode.equalsIgnoreCase("bench")){
28 System.out.println(" Client Action: " + action);
29 System.out.println(" Buffer Size : " + bufsize);
30 System.out.println(" Iterations : " + num);
31 }
32
33 if (outproto.equalsIgnoreCase("RMI") || outproto.equalsIgnoreCase("SRMI")){
34 return runRMIClient(args);
35 } else if (outproto.equalsIgnoreCase("TCP")){
36 return runTCPClient(args);
37 } else if (outproto.equalsIgnoreCase("SSL")){
38 return runSSLClient(args);
39 } else if (outproto.equalsIgnoreCase("HTTP")){
40 return processReadURL(args, num, bufsize, mode, verbose);
41 } else if (outproto.equalsIgnoreCase("HTTPS")){
42 return processReadURL(args, num, bufsize, mode, verbose);
43 }
44 return new JSTKResult(null, false, "Unknown OUT Protocol: " + outproto);
45 } catch (Exception exc){
46 throw new JSTKException("ClientCommand execution failed", exc);
47 }
48 }
49
50 public static void main(String[] args) throws Exception {
51 JSTKOptions opts = new JSTKOptions();
52 opts.parse(args, 0);
53 ClientCommand clientCmd = new ClientCommand();
54 JSTKResult result = (JSTKResult)clientCmd.execute(opts);
55 System.out.println(result.getText());
56 System.exit(result.isSuccess()? 0 : 1);
57 }
58}
59