/**
* Copyright (c) 2007-2009 Alysson Bessani, Eduardo Alchieri, Paulo Sousa, and the authors indicated in the @author tags
*
* This file is part of SMaRt.
*
* SMaRt is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SMaRt is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with SMaRt. If not, see <http://www.gnu.org/licenses/>.
*/
package bftsmart.clientsmanagement;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.util.Iterator;
import java.util.concurrent.locks.ReentrantLock;
import bftsmart.tom.core.messages.TOMMessage;
import bftsmart.tom.util.Logger;
import bftsmart.tom.util.TOMUtil;
public class ClientData {
ReentrantLock clientLock = new ReentrantLock();
private int clientId;
//private PublicKey publicKey = null;
private int session = -1;
private int lastMessageReceived = -1;
private long lastMessageReceivedTime = 0;
private int lastMessageExecuted = -1;
private RequestList pendingRequests = new RequestList();
//anb: new code to deal with client requests that arrive after their execution
private RequestList orderedRequests = new RequestList(5);
private Signature signatureVerificator = null;
/**
* Class constructor. Just store the clientId and creates a signature
* verificator for a given client public key.
*
* @param clientId client unique id
* @param publicKey client public key
*/
public ClientData(int clientId, PublicKey publicKey) {
this.clientId = clientId;
if(publicKey != null) {
try {
signatureVerificator = Signature.getInstance("SHA1withRSA");
signatureVerificator.initVerify(publicKey);
Logger.println("Signature verifier initialized for client "+clientId);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
public int getClientId() {
return clientId;
}
public int getSession() {
return session;
}
public void setSession(int session) {
this.session = session;
}
public RequestList getPendingRequests() {
return pendingRequests;
}
public RequestList getOrderedRequests() {
return orderedRequests;
}
public void setLastMessageExecuted(int lastMessageExecuted) {
this.lastMessageExecuted = lastMessageExecuted;
}
public int getLastMessageExecuted() {
return lastMessageExecuted;
}
public void setLastMessageReceived(int lastMessageReceived) {
this.lastMessageReceived = lastMessageReceived;
}
public int getLastMessageReceived() {
return lastMessageReceived;
}
public void setLastMessageReceivedTime(long lastMessageReceivedTime) {
this.lastMessageReceivedTime = lastMessageReceivedTime;
}
public long getLastMessageReceivedTime() {
return lastMessageReceivedTime;
}
public boolean verifySignature(byte[] message, byte[] signature) {
if(signatureVerificator != null) {
try {
return TOMUtil.verifySignature(signatureVerificator, message, signature);
} catch (SignatureException ex) {
System.err.println("Error in processing client "+clientId+" signature: "+ex.getMessage());
}
}
return false;
}
public boolean removeOrderedRequest(TOMMessage request) {
if(pendingRequests.remove(request)) {
//anb: new code to deal with client requests that arrive after their execution
orderedRequests.addLast(request);
return true;
}
return false;
}
public boolean removeRequest(TOMMessage request) {
lastMessageExecuted = request.getSequence();
boolean result = pendingRequests.remove(request);
//anb: new code to deal with client requests that arrive after their execution
orderedRequests.addLast(request);
for(Iterator<TOMMessage> it = pendingRequests.iterator();it.hasNext();){
TOMMessage msg = it.next();
if(msg.getSequence()<request.getSequence()){
it.remove();
}
}
return result;
}
public TOMMessage getReply(int reqId) {
TOMMessage request = orderedRequests.getById(reqId);
if(request != null) {
return request.reply;
} else {
return null;
}
}
}