/**
* OnionCoffee - Anonymous Communication through TOR Network
* Copyright (C) 2005-2007 RWTH Aachen University, Informatik IV
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
package TorJava;
import java.io.IOException;
import TorJava.Common.QueueHandler;
import TorJava.Common.TorException;
/** convenient way to handle flow-control
*
* @author Lexi
*/
class QueueFlowControlHandler implements QueueHandler {
int counter;
int currLevel;
int startLevel;
int incLevel;
Circuit circ;
TCPStream stream;
boolean circuitLevel;
QueueFlowControlHandler(Circuit circ,int startLevel,int incLevel) {
this.circ = circ;
this.counter = 0;
this.startLevel = startLevel;
this.currLevel = startLevel;
this.incLevel = incLevel;
}
QueueFlowControlHandler(TCPStream stream,int startLevel,int incLevel) {
this.stream = stream;
this.counter = 0;
this.startLevel = startLevel;
this.currLevel = startLevel;
this.incLevel = incLevel;
}
private synchronized void count() {
--currLevel;
++counter;
}
private synchronized void increase() {
currLevel += incLevel;
}
/** return TRUE, if cell was handled */
public boolean handleCell(Cell cell)
throws TorException
{
count();
// dropped below threshold - oh no!
// better start sending SENDMEs...
if (currLevel<=startLevel-incLevel) {
try {
if (circ != null) {
// send to all routers in the circuit
Logger.logCircuit(Logger.VERBOSE,"QueueFlowControlHandler.mainAction(): ("+counter+") "+currLevel+"<"+startLevel+" sending SENDME for circuit "+circ.print());
for(int i=0;i<circ.route_established;++i)
circ.send_cell(new CellRelaySendme(circ,i));
};
if (stream != null) {
// send to end-point
Logger.logStream(Logger.VERBOSE,"QueueFlowControlHandler.mainAction(): ("+counter+") "+currLevel+"<"+startLevel+" sending SENDME for stream "+stream.print());
stream.send_cell(new CellRelaySendme(stream));
};
increase();
}
catch(IOException e) {
if (circ != null)
Logger.logCircuit(Logger.WARNING,"QueueFlowControlHandler.mainAction(): error sending SENDME "+e.getMessage());
if (stream != null)
Logger.logStream(Logger.WARNING,"QueueFlowControlHandler.mainAction(): error sending SENDME "+e.getMessage());
}
};
// always return FALSE to avoid swallowing cells
return false;
}
/** close these things */
public void close() {
}
}