Never Finishes Final While Loop - java

I have an assignment where I basically have to write a small botnet. We have been given a list of usernames and encrypted passwords. We have also been given the code to decrypt these passwords. The assignment is to use TCP to crack the passwords in a Master/Slave relationship. The password cracking is like a Dictionary attack in which you compare the encrypted passwords to a dictionary.
This means that a Master (Server) have to send instructions out to Slaves (Clients). These instructions are encrypted passwords, and where in the diciontary to start looking so that different slaves can check different parts of the dicionary at the same time, speeding up the process of decrypting.
Personally I have to take care of the Master. The process works as such:
A Master (Class) starts a Session (Class implementing Runnable) in a new Thread. The Session makes individual InputStreamListeners (Class implementing Runnable) for each Slave so that input can be handled on separate threads. When the Slave is done, all the decrypted passwords are sent to the InputStreamListener and added to an ArrayList of strings. This list will then be sent to the Session, and hopefully added to a list of ArrayLists (so ArrayList>). The Session do receive all the passwords. The Socket gets closed in the InputStreamListener and the Slave shuts down. This to me, would mean that the task for that listener should now be shutdown, and not be in the ExecutorService thread pool any more.
We have only been working with 1 slave at a time, so far. When the InputStreamListener close ends, the code looks like this:
try {
writer.println("Disconnecting Slave...");
scanner.close();
writer.close();
slave.getSocket().close();
Master.messageServer("Slave Socket Close");
} catch (IOException ex) {
Master.messageServer("[" + ip + "]: Problem closing Socket for Slave: ");
Master.messageServer("[" + ip + "]:" + ex.getMessage());
}
while(true) {
Master.messageServer("Trying Lock");
if(session.lock.tryLock()) {
try {
session.addResults(results);
Master.messageServer("Added Results to Session.");
break;
} finally {
session.lock.unlock();
}
}
}
The InputStreamListener reaches the while loop but only prints "Trying Lock" once. If it was locked this means that the Console should now be spammed with "Trying Lock" until it can actually reach the method and then print "Added results to Session".
The code in the session looks like this:
public void addResults(ArrayList<String> list) {
lock.lock();
try {
results.add(list);
} finally {
lock.unlock();
}
}
The lock is a ReentrantLock.
This is of course done, so that 2 or more InputStreamListeners don't access the method at the same time.
I simply can't find out why this happens, and why the program won't work. Logically it seems to be working. Other than this, it just puts the information into a new method to create a txt file. Help?

Related

Call a method of all parallel Class Threads

I have a question for you.
I have multiple Threads runnings of a class called ServerThread. When an specific event happens on ANY of those threads, I want to call a method of every other thread running in parallel.
public class ServerThread implements Runnable {
private TCPsocket clientSocket;
public ServerThread(Socket comSocket){
clientSocket = new TCPsocket(comSocket);
}
#Override
public void run(){
boolean waiting = true;
Message msg;
try{
while(waiting){
msg = clientSocket.getMessage();
shareMessage(msg);
}
}catch(Exception e){
ErrorLogger.toFile("EndConnection", e.toString());
}
}
public void shareMessage(Message msg){
clientSocket.sendMessage(msg);
}
}
I am talking about this specific line
shareMessage(msg);
which I would like to be called on every thread/instance
-- so that a message is sent to every client (in all tcp connections)
I've tried with synchronized but either I'm not using it well or that is not what I am looking for.
Another thing that might work is keeping a class with an static member which is a list of those tcpconnection objects and then do some loop in all every time.
Thanks for your help and time.
Edited with one possible solution
*Add an static array as a member of the class and add/remove objects of same class (or tcp sockets would also work)
private static ArrayList<ServerThread> handler;
...
handler.add(this);
...
handler.remove(this); //when client exists and thread stops
*Then create a method that iterates for each connection, and make it synchronized so that two threads won't interact at the same time. You may want to implement synchronized on your message sending methods as well.
public void shareMessage(Message msg){
//this.clientSocket.sendMessage(msg);
synchronized (handler){
for(ServerThread connection: handler){
try{
connection.clientSocket.sendMessage(msg);
} catch(Exception e){
connection.clientSocket.closeConnection();
}
}
}
}
First: synchronized is required to prevent race conditions when multiple threads want to call the same method and this method accesses/modifies shared data. So maybe (probably) you will need it somewhere but it does not provide you the functionality you require.
Second: You cannot command an other thread to call a method directly. It is not possible e.g. for ThreadA to call methodX in ThreadB.
I guess you have one thread per client. Probably each thread will block at clientSocket.getMessage() until the client sends a message. I don't know the implementation of TCPsocket but maybe it is possible to interrupt the thread. In this case you may need to catch a InterruptedException and ask some central data structure if the interrupt was caused because of a new shared message and to return the shared message.
Maybe it is also possible for TCPsocket.getMessage() to return, if no message was received for some time, in which case you would again have to ask a central data structure if there is a new shared message.
Maybe it is also possible to store all client connections in such a data structure and loop them every time, as you suggested. But keep in mind that the client might send a message at any time, maybe even at the exact same time when you try to send it the shared message received from another client. This might be no problem but this depends on your application. Also you have to consider that the message will also be shared with the client that sent it to your server in the first place…
Also take a look at java.util.concurrent and its subpackages, it is likely you find something useful there… ;-)
To summarize: There are many possibilities. Which one is the best depends on what you need. Please add some more detail to your question if you need more specific help.

How do I communicate with all threads on a Multithreaded server?

Ok. I'm trying to grasp some multithreading Java concepts. I know how to set up a multiclient/server solution. The server will start a new thread for every connected client.
Conceptually like this...
The loop in Server.java:
while (true) {
Socket socket = serverSocket.accept();
System.out.println(socket.getInetAddress().getHostAddress() + " connected");
new ClientHandler(socket).start();
}
The ClientHandler.java loop is:
while(true)
{
try {
myString = (String) objectInputStream.readObject();
}
catch (ClassNotFoundException | IOException e) {
break;
}
System.out.println(myClientAddress + " sent " + myString);
try {
objectOutputStream.writeObject(someValueFromTheServer);
objectOutputStream.flush();
}
catch (IOException e) {
return;
}
}
This is just a concept to grasp the idea. Now, I want the server to be able to send the same object or data at the same time - to all clients.
So somehow I must get the Server to speak to every single thread. Let's say I want the server to generate random numbers with a certain time interval and send them to the clients.
Should I use properties in the Server that the threads can access? Is there a way to just call a method in the running threads from the main thread? I have no clue where to go from here.
Bonus question:
I have another problem too... Which might be hard to see in this code. But I want every client to be able to receive messages from the server AND send messages to the sever independently. Right now I can get the Client to stand and wait for my gui to give something to send. After sending, the Client will wait for the server to send something back that it will give to the gui. You can see that my ClientHandler has that problem too.
This means that while the Client is waiting for the server to send something it cannot send anything new to the server. Also, while the Client is waiting for the gui to give it something to send, it cannot receive from the server.
I have only made a server/client app that uses the server to process data it receives from the Client - and the it sends the processed data back.
Could anyone point me in any direction with this? I think I need help how to think conceptually there. Should I have two different ClientHandlers? One for the instream and one for the outstream? I fumbling in the dark here.
"Is there a way to just call a method in the running threads from the main thread?"
No.
One simple way to solve your problem would be to have the "server" thread send the broadcast to every client. Instead of simply creating new Client objects and letting them go (as in your example), it could keep all of the active Client objects in a collection. When it's time to send a broadcast message, it could iterate over all of the Client objects, and call a sendBroadcast() method on each one.
Of course, you would have to synchronize each client thread's use of a Client object outputStream with the server thread's use of the same stream. You also might have to deal with client connections that don't last forever (their Client objects must somehow be removed from the collection.)

about socket.startHandshake(); in java

I have a small Java program that reads list of IPs from text file and inside a loop it create ssl session with the ip. The session might succeed or fail depend whether the port 443 is enabled in the other side or not.
My problem:
1. If port 443 is not enabled in the other side, the session will fail. The problem is that my program stops here and go to exception handling and print me the error and ends. I want the program to continue creating the next session with the next IP and so on. How can I make it continue and print out a message saying that the session failed for that IP?
Another issue: How can I get the enabled cipher suite? I tried to print socket.getEnabledCipherSuites(); but printed strange text not a type of cipher suite at all.
EDIT:
public static void main(String[] argv) {
try{
while ((there are IPs)
{
try{
//call for Connect function which has try/catch on it the same way
}catch (Exception e){
System.err.println("Error: " + e.getMessage());
}//catch
}//end while loop
catch (Exception e){
System.err.println("Error: " + e.getMessage());
}//catch
}//end void main </i>
your point #1 seems to be something exception handling should take care of: enclose each iteration on all_ips within its own try/catch block.
You could greatly benefit from some multithreading and time-out here, as some firewall will just drop your SYN packet silently and let your scanner tool wait indefinitely.
BUT before you do that, take care: you're going to look very much like a malicious tool scanning a network for some vulnerabilities. You may get into administrative trouble if you're too aggressive or target someone you don't know. A pool of thread or some similar technique to ensure you're not exceeding fair amount of connection establishment/second is a bare minimum.

Which is a suitable architecture?

I have tested a socket connection programme with the idea where the socket connection will be one separate thread by itself and then it will enqueue and another separate thread for dbprocessor will pick from the queue and run through a number of sql statement. So I notice here is where the bottle neck that the db processing. I would like to get some idea is what I am doing the right architecture or I should change or improve on my design flow?
The requirement is to capture data via socket connections and run through a db process then store it accordingly.
public class cServer
{
private LinkedBlockingQueue<String> databaseQueue = new LinkedBlockingQueue<String>();
class ConnectionHandler implements Runnable {
ConnectionHandler(Socket receivedSocketConn1) {
this.receivedSocketConn1=receivedSocketConn1;
}
// gets data from an inbound connection and queues it for databse update
public void run(){
databaseQueue.add(message); // put to db queue
}
}
class DatabaseProcessor implements Runnable {
public void run(){
// open database connection
createConnection();
while (true){
message = databaseQueue.take(); // keep taking message from the queue add by connectionhandler and here I will have a number of queries to run in terms of select,insert and updates.
}
}
void createConnection(){
System.out.println("Crerate Connection");
connCreated = new Date();
try{
dbconn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test1?"+"user=user1&password=*******");
dbconn.setAutoCommit(false);
}
catch(Throwable ex){
ex.printStackTrace(System.out);
}
}
}
public void main()
{
new Thread(new DatabaseProcessor()).start(); //calls the DatabaseProcessor
try
{
final ServerSocket serverSocketConn = new ServerSocket(8000);
while (true){
try{
Socket socketConn1 = serverSocketConn.accept();
new Thread(new ConnectionHandler(socketConn1)).start();
}
catch(Exception e){
e.printStackTrace(System.out);
}
}
}
catch (Exception e){
e.printStackTrace(System.out);
}
}
}
It's hard (read 'Impossible') to judge a architecture without the requirements. So I will just make some up:
Maximum Throughput:
Don't use a database, write to a flatfile, possibly stored on something fast like a solid state disc.
Guaranteed Persistence (If the user gets an answer not consisting of an error, the data must be stored securely):
Make the whole thing single threaded, save everything in a database with redundant discs. Make sure you have a competent DBA who knows about Back up and Recovery. Test those on regular intervals.
Minimum time for finishing the user request:
Your approach seems reasonable.
Minimum time for finishing the user request + Maximizing Throughput + Good Persistence (what ever that means):
Your approach seems good. You might plan for multiple threads processing the DB requests. But test how much (more) throughput you actually get and where precisely the bottleneck is (Network, DB CPU, IO, Lock contention ...). Make sure you don't introduce bugs by using a concurrent approach.
Generally, your architecture sounds correct. You need to make sure that your two threads are synchronised correctly when reading/writing from/to the queue.
I am not sure what you mean by "bottle neck that the db processing"? If DB processing takes a long time and and you end up with a long queue, there's not much you can do apart from having multiple threads performing the DB processing (assuming the processing can be parallelised, of course) or do some performance tuning in the DB thread.
If you post some specific code that you believe is causing the problem, we can have another look.
You don't need two threads for this simple task. Just read the socket and execute the statements.

two serial tasks slower than parallel

Hi I have a webapp - and in one method I need to encrypt part of data from request and store them on disk and return response.
Response is in no way related to encryption.
The encryption is quite time demanding however. How to make threads or so properly in this problem?
I tried something like
Thread thread ...
thread.start();
or
JobDetail job = encryptionScheduler.getJobDetail(jobDetail.getName(), jobDetail.getGroup());
encryptionScheduler.scheduleJob(jobDetail,TriggerUtils.makeImmediateTrigger("encryptionTrigger",1,1)
I tried servlet where before encryption I close the outpuStream.
or: Executors.newFixedThreadPool(1);
But whatever I tried a client has to wait longer.
btw: why is that so? Can it be faster?
I haven't tried to start thread after context initalization and wait somehow for method needing encryption.
how to speed up this?
thank you
--------------EDIT:
//I use axis 1.4, where I have Handler, which in invoke method encrypt a value:
try {
LogFile logFile = new LogFile(strategy,nodeValue,path, new Date());
LogQueue.queue.add(logFile);
}
catch (Exception e) {
log.error(e.getMessage(),e);
}
EExecutor.executorService.execute(new Runnable() {
public void run() {
try {
LogFile poll = LogQueue.queue.poll();
String strategy = poll.getStrategy();
String value = poll.getNodeValue();
value = encrypt(strategy,value);
PrintWriter writer = new PrintWriter(new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(poll.getPath(), true )),"UTF-8"));
writer.print(value);
writer.close();
}catch (IOException e ) {
log.error(e.getMessage(),e);
}
}
});
} catch (Throwable e ) {
log.error(e.getMessage(),e);
}
//besides I have executor service
public class EExecutor { public static ExecutorService executorService = Executors.newCachedThreadPool();}
//and what's really interesting.. when I move encryption from this handler away into another handler which is called
last when I send response! It's faster. But when I leave it in one of the first handlers when I receive request. It's even slower without using threads/servlet etc.
Threads only help you if parts of your task can be done in parallel. It sounds like you're waiting for the encryption to finish before returning the result. If it's necessary for you to do that (e.g., because the encrypted data is the result) then doing the encryption on a separate thread won't help you here---all it will do is introduce the overhead of creating and switching to a different thread.
Edit: If you're starting a new thread for each encryption you do, then that might be part of your problem. Creating new threads is relatively expensive. A better way is to use an ExecutorService with an unbounded queue. If you don't care about the order in which the encryption step happens (i.e., if it's ok that the encryption which started due to a request at time t finishes later than one which started at time t', and t < t'), then you can let the ExecutorService have more than a single thread. That will give you both greater concurrency and save you the overhead of recreating threads all the time, since an ExecutorService pools and reuses threads.
The proper way to do something like this is to have a message queue, such as the standard J2EE JMS.
In a message queue, you have one software component whose job it is to receive messages (such as requests to encrypt some resource, as in your case), and make the request "durable" in a transactional way. Then some independent process polls the message queue for new messages, takes action on them, and transactionally marks the messages as received.

Categories

Resources