/********************************************************* {COPYRIGHT-TOP} *** * Copyright 2016 IBM Corporation * * All rights reserved. This program and the accompanying materials * are made available under the terms of the MIT License * which accompanies this distribution, and is available at * http://opensource.org/licenses/MIT ********************************************************** {COPYRIGHT-END} **/ package com.ibm.uk.hursley.perfharness.tcpip; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; import java.net.UnknownHostException; import java.util.logging.Level; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; import com.ibm.uk.hursley.perfharness.Config; import com.ibm.uk.hursley.perfharness.Log; public class TCPIPProviderBase { protected static byte[][] messageData = null; protected static String hostname = null; protected static int port; private static int currentPort; private static int portRange; private static int timeoutIntervalLength = 500; public static int timeoutNumIntervals = 20; private static InetAddress addr; private static final String msgEncoding = "UTF8"; public static boolean USE_NP_CONNECTIONS = false; public static boolean USE_SECURE = false; public static String[] SECURE_PROTO = null; protected void setupProvider() { port = Config.parms.getInt("jp"); currentPort = port; portRange = Config.parms.getInt("dn"); timeoutIntervalLength = Config.parms.getInt("ri"); timeoutNumIntervals = Config.parms.getInt("to") / timeoutIntervalLength; hostname = Config.parms.getString("jh"); USE_NP_CONNECTIONS = Config.parms.getBoolean("cs"); USE_SECURE = Config.parms.getBoolean("se"); final String sSecureProto = Config.parms.getString("ps"); SECURE_PROTO = ((sSecureProto != null) && (sSecureProto.length() > 0)) ? sSecureProto.split(",") : null; Log.logger.log(Level.INFO, "ThreadID " + Thread.currentThread().getId()); } public int getNumMessages() { return messageData.length; } public int getMessageSize(int k) { return messageData[k].length; } public String getStringMessage(int k) throws Exception { return new String(messageData[k], msgEncoding); } public byte[] getBytesMessage(int k) throws Exception { return messageData[k]; } public int getMessageIndex(int iIter, int iThread) { final int msgPattern = Config.parms.getInt("pa"); if (msgPattern == 1) { // PRIME return Math.min(iIter, getNumMessages() - 1); } else if (msgPattern == 2) { // THREAD return iThread % getNumMessages(); } else { // CYCLE return iIter % getNumMessages(); } } public void loadMessages() throws Exception { final String[] messageFiles = Config.parms.getCSStringList("mf"); if ((messageData != null) && (messageData.length == messageFiles.length)) // the messages have already been loaded return; messageData = new byte[messageFiles.length][]; for (int k = 0; k < messageFiles.length; k++) { try { messageData[k] = loadMessageFromFile(messageFiles[k]); } catch (IOException ioe) { Log.logger.log(Level.SEVERE, "Cannot read file \"" + messageFiles[k] + "\"", ioe); System.exit(1); } } } public static byte[] loadMessageFromFile(String fileName) throws IOException { if (fileName.isEmpty()) // no file has been specified, return an empty byte array return new byte[0]; final File f = new File(fileName); final FileInputStream fis = new FileInputStream(f); try { final long msgSize = (int)f.length(); if (msgSize > (long)Integer.MAX_VALUE) throw new IOException("File is too large"); final byte[] data = new byte[(int)msgSize]; fis.read(data); return data; } finally { fis.close(); } } public Socket getSocket() throws IOException { getHostname(); final Socket socket = new Socket(); socket.setTcpNoDelay(true); socket.setReuseAddress(true); socket.setSoLinger(true, 0); socket.setSoTimeout(timeoutIntervalLength); socket.connect(new InetSocketAddress(addr, currentPort), 0); // Check to see if the user has requested a range of ports to be used if (portRange > 1) { // For a range of ports, keep incrementing up to the max range and then // loop back to the start if (currentPort >= port + portRange - 1) currentPort = port; else currentPort++; } return socket; } public Socket getSSLSocket() throws IOException { getHostname(); final SSLSocketFactory sf = (SSLSocketFactory)SSLSocketFactory.getDefault(); if (portRange > 1) System.out.println("About to connect to port " + currentPort + " for thread " + Thread.currentThread()); final SSLSocket socket = (SSLSocket)sf.createSocket(); if (SECURE_PROTO != null) socket.setEnabledProtocols(SECURE_PROTO); socket.setReuseAddress(true); socket.setSoLinger(true, 0); socket.setSoTimeout(timeoutIntervalLength); socket.connect(new InetSocketAddress(addr, currentPort), 0); // Check to see if the user has requested a range of ports to be used if (portRange > 1) { // For a range of ports, keep incrementing up to the max range and then // loop back to the start if (currentPort >= port + portRange - 1) currentPort = port; else currentPort++; } return socket; } public void getHostname() { final String[] hostArray = hostname.split("[,]"); final String threadHostName = hostArray[(int)((((Thread.currentThread().getId() - 13) % hostArray.length) + 1) - 1)]; if (hostArray.length > 1) Log.logger.log(Level.INFO, "Connecting to " + threadHostName); try { addr = InetAddress.getByName(threadHostName); } catch (UnknownHostException e) { Log.logger.log(Level.SEVERE, "Cannot resolve Hostname " + threadHostName, e); System.exit(1); } } }