2007-11-14 22:18:48 -05:00
|
|
|
/*
|
|
|
|
* "$Id: pqihandler.cc,v 1.12 2007-03-31 09:41:32 rmf24 Exp $"
|
|
|
|
*
|
|
|
|
* 3P/PQI network interface for RetroShare.
|
|
|
|
*
|
|
|
|
* Copyright 2004-2006 by Robert Fernie.
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Library General Public
|
|
|
|
* License Version 2 as published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* This library 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
|
|
|
|
* Library General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Library General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
|
|
|
* USA.
|
|
|
|
*
|
|
|
|
* Please report all bugs and problems to "retroshare@lunamutt.com".
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "pqi/pqihandler.h"
|
|
|
|
|
|
|
|
#include <sstream>
|
|
|
|
#include "pqi/pqidebug.h"
|
|
|
|
const int pqihandlerzone = 34283;
|
|
|
|
|
|
|
|
|
|
|
|
pqihandler::pqihandler(SecurityPolicy *Global)
|
|
|
|
{
|
|
|
|
// The global security....
|
|
|
|
// if something is disabled here...
|
|
|
|
// cannot be enabled by module.
|
|
|
|
globsec = Global;
|
|
|
|
|
|
|
|
{
|
|
|
|
std::ostringstream out;
|
|
|
|
out << "New pqihandler()" << std::endl;
|
|
|
|
out << "Security Policy: " << secpolicy_print(globsec);
|
|
|
|
out << std::endl;
|
|
|
|
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, out.str());
|
|
|
|
}
|
|
|
|
|
|
|
|
// setup minimal total+individual rates.
|
|
|
|
rateIndiv_out = 0.01;
|
|
|
|
rateIndiv_in = 0.01;
|
|
|
|
rateMax_out = 0.01;
|
|
|
|
rateMax_in = 0.01;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
int pqihandler::tick()
|
|
|
|
{
|
|
|
|
// tick all interfaces...
|
2007-12-11 20:29:14 -05:00
|
|
|
std::map<std::string, SearchModule *>::iterator it;
|
2007-11-14 22:18:48 -05:00
|
|
|
int moreToTick = 0;
|
|
|
|
for(it = mods.begin(); it != mods.end(); it++)
|
|
|
|
{
|
|
|
|
if (0 < ((it -> second) -> pqi) -> tick())
|
|
|
|
{
|
|
|
|
moreToTick = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// get the items, and queue them correctly
|
|
|
|
if (0 < GetItems())
|
|
|
|
{
|
|
|
|
moreToTick = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
UpdateRates();
|
|
|
|
return moreToTick;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int pqihandler::status()
|
|
|
|
{
|
2007-12-11 20:29:14 -05:00
|
|
|
std::map<std::string, SearchModule *>::iterator it;
|
2007-11-14 22:18:48 -05:00
|
|
|
|
|
|
|
{ // for output
|
|
|
|
std::ostringstream out;
|
|
|
|
out << "pqihandler::status() Active Modules:" << std::endl;
|
|
|
|
|
|
|
|
// display all interfaces...
|
|
|
|
for(it = mods.begin(); it != mods.end(); it++)
|
|
|
|
{
|
|
|
|
out << "\tModule [" << it -> first << "] Pointer <";
|
|
|
|
out << (void *) ((it -> second) -> pqi) << ">" << std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, out.str());
|
|
|
|
|
|
|
|
} // end of output.
|
|
|
|
|
|
|
|
|
|
|
|
// status all interfaces...
|
|
|
|
for(it = mods.begin(); it != mods.end(); it++)
|
|
|
|
{
|
|
|
|
((it -> second) -> pqi) -> status();
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2007-12-11 20:29:14 -05:00
|
|
|
bool pqihandler::AddSearchModule(SearchModule *mod)
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
2007-12-11 20:29:14 -05:00
|
|
|
// if peerid used -> error.
|
|
|
|
std::map<std::string, SearchModule *>::iterator it;
|
|
|
|
if (mod->peerid != mod->pqi->PeerId())
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
2007-12-11 20:29:14 -05:00
|
|
|
// ERROR!
|
|
|
|
std::ostringstream out;
|
|
|
|
out << "ERROR peerid != PeerId!" << std::endl;
|
|
|
|
pqioutput(PQL_ALERT, pqihandlerzone, out.str());
|
|
|
|
return false;
|
2007-11-14 22:18:48 -05:00
|
|
|
}
|
2007-12-11 20:29:14 -05:00
|
|
|
|
|
|
|
if (mod->peerid == "")
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
2007-12-11 20:29:14 -05:00
|
|
|
// ERROR!
|
|
|
|
std::ostringstream out;
|
|
|
|
out << "ERROR peerid == NULL" << std::endl;
|
|
|
|
pqioutput(PQL_ALERT, pqihandlerzone, out.str());
|
|
|
|
return false;
|
|
|
|
}
|
2007-11-14 22:18:48 -05:00
|
|
|
|
2007-12-11 20:29:14 -05:00
|
|
|
if (mods.find(mod->peerid) != mods.end())
|
|
|
|
{
|
|
|
|
// ERROR!
|
|
|
|
std::ostringstream out;
|
|
|
|
out << "ERROR PeerId Module already exists!" << std::endl;
|
|
|
|
pqioutput(PQL_ALERT, pqihandlerzone, out.str());
|
|
|
|
return false;
|
2007-11-14 22:18:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// check security.
|
|
|
|
if (mod -> sp == NULL)
|
|
|
|
{
|
|
|
|
// create policy.
|
|
|
|
mod -> sp = secpolicy_create();
|
|
|
|
}
|
|
|
|
|
|
|
|
// limit to what global security allows.
|
|
|
|
secpolicy_limit(globsec, mod -> sp);
|
|
|
|
|
|
|
|
// store.
|
2007-12-11 20:29:14 -05:00
|
|
|
mods[mod->peerid] = mod;
|
|
|
|
return true;
|
2007-11-14 22:18:48 -05:00
|
|
|
}
|
|
|
|
|
2007-12-11 20:29:14 -05:00
|
|
|
bool pqihandler::RemoveSearchModule(SearchModule *mod)
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
2007-12-11 20:29:14 -05:00
|
|
|
std::map<std::string, SearchModule *>::iterator it;
|
2007-11-14 22:18:48 -05:00
|
|
|
for(it = mods.begin(); it != mods.end(); it++)
|
|
|
|
{
|
|
|
|
if (mod == it -> second)
|
|
|
|
{
|
|
|
|
mods.erase(it);
|
2007-12-11 20:29:14 -05:00
|
|
|
return true;
|
2007-11-14 22:18:48 -05:00
|
|
|
}
|
|
|
|
}
|
2007-12-11 20:29:14 -05:00
|
|
|
return false;
|
2007-11-14 22:18:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// dummy output check
|
2007-12-11 20:29:14 -05:00
|
|
|
int pqihandler::checkOutgoingRsItem(RsItem *item, int global)
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
|
|
|
pqioutput(PQL_WARNING, pqihandlerzone,
|
|
|
|
"pqihandler::checkOutgoingPQItem() NULL fn");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// generalised output
|
2007-12-11 20:29:14 -05:00
|
|
|
int pqihandler::HandleRsItem(RsItem *item, int allowglobal)
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
2007-12-11 20:29:14 -05:00
|
|
|
std::map<std::string, SearchModule *>::iterator it;
|
2007-11-14 22:18:48 -05:00
|
|
|
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone,
|
2007-12-11 20:29:14 -05:00
|
|
|
"pqihandler::HandleRsItem()");
|
2007-11-14 22:18:48 -05:00
|
|
|
|
2007-12-11 20:29:14 -05:00
|
|
|
/* simplified to no global! */
|
|
|
|
if (allowglobal)
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
2007-12-11 20:29:14 -05:00
|
|
|
/* error */
|
2007-11-14 22:18:48 -05:00
|
|
|
std::ostringstream out;
|
2007-12-11 20:29:14 -05:00
|
|
|
out << "pqihandler::HandleSearchItem()";
|
|
|
|
out << " Cannot send out Global RsItem";
|
|
|
|
pqioutput(PQL_ALERT, pqihandlerzone, out.str());
|
|
|
|
delete item;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!checkOutgoingRsItem(item, allowglobal))
|
|
|
|
{
|
|
|
|
std::ostringstream out;
|
|
|
|
out << "pqihandler::HandleRsItem() checkOutgoingPQItem";
|
2007-11-14 22:18:48 -05:00
|
|
|
out << " Failed on item: " << std::endl;
|
|
|
|
item -> print(out);
|
|
|
|
|
2007-12-11 20:29:14 -05:00
|
|
|
pqioutput(PQL_ALERT, pqihandlerzone, out.str());
|
2007-11-14 22:18:48 -05:00
|
|
|
delete item;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2007-12-11 20:29:14 -05:00
|
|
|
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone,
|
|
|
|
"pqihandler::HandleRsItem() Sending to One Channel");
|
2007-11-14 22:18:48 -05:00
|
|
|
|
|
|
|
|
2007-12-11 20:29:14 -05:00
|
|
|
// find module.
|
|
|
|
if ((it = mods.find(item->PeerId())) == mods.end())
|
|
|
|
{
|
|
|
|
std::ostringstream out;
|
|
|
|
out << "pqihandler::HandleRsItem() Invalid chan!";
|
|
|
|
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, out.str());
|
2007-11-14 22:18:48 -05:00
|
|
|
|
2007-12-11 20:29:14 -05:00
|
|
|
delete item;
|
|
|
|
return -1;
|
|
|
|
}
|
2007-11-14 22:18:48 -05:00
|
|
|
|
2007-12-11 20:29:14 -05:00
|
|
|
// check security... is output allowed.
|
|
|
|
if(0 < secpolicy_check((it -> second) -> sp, 0, PQI_OUTGOING))
|
|
|
|
{
|
|
|
|
std::ostringstream out;
|
|
|
|
out << "pqihandler::HandleRsItem() sending to chan:";
|
|
|
|
out << it -> first << std::endl;
|
|
|
|
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, out.str());
|
2007-11-14 22:18:48 -05:00
|
|
|
|
2007-12-11 20:29:14 -05:00
|
|
|
// if yes send on item.
|
|
|
|
((it -> second) -> pqi) -> SendItem(item);
|
|
|
|
return 1;
|
2007-11-14 22:18:48 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-12-11 20:29:14 -05:00
|
|
|
std::ostringstream out;
|
|
|
|
out << "pqihandler::HandleRsItem()";
|
|
|
|
out << " Sec not approved";
|
|
|
|
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, out.str());
|
2007-11-14 22:18:48 -05:00
|
|
|
|
|
|
|
delete item;
|
2007-12-11 20:29:14 -05:00
|
|
|
return -1;
|
2007-11-14 22:18:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// if successfully sent to at least one.
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2007-12-11 20:29:14 -05:00
|
|
|
int pqihandler::SearchSpecific(RsCacheRequest *ns)
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
2007-12-11 20:29:14 -05:00
|
|
|
return HandleRsItem(ns, 0);
|
2007-11-14 22:18:48 -05:00
|
|
|
}
|
|
|
|
|
2007-12-11 20:29:14 -05:00
|
|
|
int pqihandler::SendSearchResult(RsCacheItem *ns)
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
2007-12-11 20:29:14 -05:00
|
|
|
return HandleRsItem(ns, 0);
|
2007-11-14 22:18:48 -05:00
|
|
|
}
|
|
|
|
|
2007-12-11 20:29:14 -05:00
|
|
|
int pqihandler::SendFileRequest(RsFileRequest *ns)
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
2007-12-11 20:29:14 -05:00
|
|
|
return HandleRsItem(ns, 0);
|
2007-11-14 22:18:48 -05:00
|
|
|
}
|
|
|
|
|
2007-12-11 20:29:14 -05:00
|
|
|
int pqihandler::SendFileData(RsFileData *ns)
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
2007-12-11 20:29:14 -05:00
|
|
|
return HandleRsItem(ns, 0);
|
2007-11-14 22:18:48 -05:00
|
|
|
}
|
|
|
|
|
2007-12-11 20:29:14 -05:00
|
|
|
int pqihandler::SendRsRawItem(RsRawItem *ns)
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
|
|
|
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone,
|
2007-12-11 20:29:14 -05:00
|
|
|
"pqihandler::SendRsRawItem()");
|
|
|
|
return HandleRsItem(ns, 0);
|
2007-11-14 22:18:48 -05:00
|
|
|
}
|
|
|
|
|
2007-12-11 20:29:14 -05:00
|
|
|
|
2007-11-14 22:18:48 -05:00
|
|
|
// inputs. This is a very basic
|
|
|
|
// system that is completely biased and slow...
|
|
|
|
// someone please fix.
|
|
|
|
|
|
|
|
int pqihandler::GetItems()
|
|
|
|
{
|
2007-12-11 20:29:14 -05:00
|
|
|
std::map<std::string, SearchModule *>::iterator it;
|
2007-11-14 22:18:48 -05:00
|
|
|
|
2007-12-11 20:29:14 -05:00
|
|
|
RsItem *item;
|
2007-11-14 22:18:48 -05:00
|
|
|
int count = 0;
|
|
|
|
|
|
|
|
// loop through modules....
|
|
|
|
for(it = mods.begin(); it != mods.end(); it++)
|
|
|
|
{
|
|
|
|
SearchModule *mod = (it -> second);
|
|
|
|
|
|
|
|
// check security... is output allowed.
|
|
|
|
if(0 < secpolicy_check((it -> second) -> sp,
|
|
|
|
PQI_ITEM_TYPE_ITEM, PQI_INCOMING))
|
|
|
|
{
|
|
|
|
// if yes... attempt to read.
|
|
|
|
while((item = (mod -> pqi) -> GetItem()) != NULL)
|
|
|
|
{
|
|
|
|
std::ostringstream out;
|
|
|
|
out << "pqihandler::GetItems() Incoming Item ";
|
|
|
|
out << " from: " << mod -> pqi << std::endl;
|
|
|
|
item -> print(out);
|
|
|
|
|
|
|
|
pqioutput(PQL_DEBUG_BASIC,
|
|
|
|
pqihandlerzone, out.str());
|
|
|
|
|
2007-12-11 20:29:14 -05:00
|
|
|
if (item->PeerId() != (mod->pqi)->PeerId())
|
|
|
|
{
|
|
|
|
/* ERROR */
|
|
|
|
pqioutput(PQL_ALERT,
|
|
|
|
pqihandlerzone, "ERROR PeerIds dont match!");
|
|
|
|
item->PeerId(mod->pqi->PeerId());
|
|
|
|
}
|
|
|
|
|
2007-11-14 22:18:48 -05:00
|
|
|
SortnStoreItem(item);
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// not allowed to recieve from here....
|
|
|
|
while((item = (mod -> pqi) -> GetItem()) != NULL)
|
|
|
|
{
|
|
|
|
std::ostringstream out;
|
|
|
|
out << "pqihandler::GetItems() Incoming Item ";
|
|
|
|
out << " from: " << mod -> pqi << std::endl;
|
|
|
|
item -> print(out);
|
|
|
|
out << std::endl;
|
|
|
|
out << "Item Not Allowed (Sec Pol). deleting!";
|
|
|
|
out << std::endl;
|
|
|
|
|
|
|
|
pqioutput(PQL_DEBUG_BASIC,
|
|
|
|
pqihandlerzone, out.str());
|
|
|
|
|
|
|
|
delete item;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2007-12-11 20:29:14 -05:00
|
|
|
void pqihandler::SortnStoreItem(RsItem *item)
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
2007-12-11 20:29:14 -05:00
|
|
|
/* get class type / subtype out of the item */
|
|
|
|
uint8_t vers = item -> PacketVersion();
|
|
|
|
uint8_t cls = item -> PacketClass();
|
|
|
|
uint8_t type = item -> PacketType();
|
|
|
|
uint8_t subtype = item -> PacketSubType();
|
|
|
|
|
|
|
|
/* whole Version reserved for SERVICES/CACHES */
|
|
|
|
if (vers == RS_PKT_VERSION_SERVICE)
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
2007-12-11 20:29:14 -05:00
|
|
|
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone,
|
|
|
|
"SortnStore -> Service");
|
|
|
|
in_service.push_back(item);
|
|
|
|
item = NULL;
|
|
|
|
return;
|
2007-11-14 22:18:48 -05:00
|
|
|
}
|
|
|
|
|
2007-12-11 20:29:14 -05:00
|
|
|
if (vers != RS_PKT_VERSION1)
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
|
|
|
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone,
|
2007-12-11 20:29:14 -05:00
|
|
|
"SortnStore -> Invalid VERSION! Deleting!");
|
|
|
|
delete item;
|
|
|
|
item = NULL;
|
|
|
|
return;
|
2007-11-14 22:18:48 -05:00
|
|
|
}
|
2007-12-11 20:29:14 -05:00
|
|
|
|
|
|
|
switch(cls)
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
2007-12-11 20:29:14 -05:00
|
|
|
case RS_PKT_CLASS_BASE:
|
|
|
|
switch(type)
|
|
|
|
{
|
|
|
|
case RS_PKT_TYPE_CACHE:
|
|
|
|
switch(subtype)
|
|
|
|
{
|
|
|
|
case RS_PKT_SUBTYPE_CACHE_REQUEST:
|
|
|
|
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone,
|
|
|
|
"SortnStore -> Cache Request");
|
|
|
|
in_search.push_back(item);
|
|
|
|
item = NULL;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RS_PKT_SUBTYPE_CACHE_ITEM:
|
|
|
|
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone,
|
|
|
|
"SortnStore -> Cache Result");
|
|
|
|
in_result.push_back(item);
|
|
|
|
item = NULL;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break; /* no match! */
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RS_PKT_TYPE_FILE:
|
|
|
|
switch(subtype)
|
|
|
|
{
|
|
|
|
case RS_PKT_SUBTYPE_FI_REQUEST:
|
|
|
|
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone,
|
|
|
|
"SortnStore -> File Request");
|
|
|
|
in_request.push_back(item);
|
|
|
|
item = NULL;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RS_PKT_SUBTYPE_FI_DATA:
|
|
|
|
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone,
|
|
|
|
"SortnStore -> File Data");
|
|
|
|
in_data.push_back(item);
|
|
|
|
item = NULL;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break; /* no match! */
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break; /* no match! */
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone,
|
|
|
|
"SortnStore -> Unknown");
|
|
|
|
break;
|
|
|
|
|
2007-11-14 22:18:48 -05:00
|
|
|
}
|
2007-12-11 20:29:14 -05:00
|
|
|
|
|
|
|
if (item)
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
2007-12-11 20:29:14 -05:00
|
|
|
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone,
|
|
|
|
"SortnStore -> Deleting Unsorted Item");
|
|
|
|
delete item;
|
2007-11-14 22:18:48 -05:00
|
|
|
}
|
2007-12-11 20:29:14 -05:00
|
|
|
|
2007-11-14 22:18:48 -05:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// much like the input stuff.
|
2007-12-11 20:29:14 -05:00
|
|
|
RsCacheItem *pqihandler::GetSearchResult()
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
|
|
|
if (in_result.size() != 0)
|
|
|
|
{
|
2007-12-11 20:29:14 -05:00
|
|
|
RsCacheItem *fi = dynamic_cast<RsCacheItem *>(in_result.front());
|
|
|
|
if (!fi) { delete in_result.front(); }
|
2007-11-14 22:18:48 -05:00
|
|
|
in_result.pop_front();
|
|
|
|
return fi;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2007-12-11 20:29:14 -05:00
|
|
|
RsCacheRequest *pqihandler::RequestedSearch()
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
2007-12-11 20:29:14 -05:00
|
|
|
if (in_search.size() != 0)
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
2007-12-11 20:29:14 -05:00
|
|
|
RsCacheRequest *fi = dynamic_cast<RsCacheRequest *>(in_search.front());
|
|
|
|
if (!fi) { delete in_search.front(); }
|
|
|
|
in_search.pop_front();
|
2007-11-14 22:18:48 -05:00
|
|
|
return fi;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2007-12-11 20:29:14 -05:00
|
|
|
RsFileRequest *pqihandler::GetFileRequest()
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
2007-12-11 20:29:14 -05:00
|
|
|
if (in_request.size() != 0)
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
2007-12-11 20:29:14 -05:00
|
|
|
RsFileRequest *fi = dynamic_cast<RsFileRequest *>(in_request.front());
|
|
|
|
if (!fi) { delete in_request.front(); }
|
|
|
|
in_request.pop_front();
|
|
|
|
return fi;
|
2007-11-14 22:18:48 -05:00
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2007-12-11 20:29:14 -05:00
|
|
|
RsFileData *pqihandler::GetFileData()
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
2007-12-11 20:29:14 -05:00
|
|
|
if (in_data.size() != 0)
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
2007-12-11 20:29:14 -05:00
|
|
|
RsFileData *fi = dynamic_cast<RsFileData *>(in_data.front());
|
|
|
|
if (!fi) { delete in_data.front(); }
|
|
|
|
in_data.pop_front();
|
|
|
|
return fi;
|
2007-11-14 22:18:48 -05:00
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2007-12-11 20:29:14 -05:00
|
|
|
RsRawItem *pqihandler::GetRsRawItem()
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
2007-12-11 20:29:14 -05:00
|
|
|
if (in_service.size() != 0)
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
2007-12-11 20:29:14 -05:00
|
|
|
RsRawItem *fi = dynamic_cast<RsRawItem *>(in_service.front());
|
|
|
|
if (!fi) { delete in_service.front(); }
|
|
|
|
in_service.pop_front();
|
|
|
|
return fi;
|
2007-11-14 22:18:48 -05:00
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const float MIN_RATE = 0.01; // 10 B/s
|
|
|
|
|
|
|
|
// internal fn to send updates
|
|
|
|
int pqihandler::UpdateRates()
|
|
|
|
{
|
2007-12-11 20:29:14 -05:00
|
|
|
std::map<std::string, SearchModule *>::iterator it;
|
2007-11-14 22:18:48 -05:00
|
|
|
int num_sm = mods.size();
|
|
|
|
|
|
|
|
float avail_in = getMaxRate(true);
|
|
|
|
float avail_out = getMaxRate(false);
|
|
|
|
|
|
|
|
float avg_rate_in = avail_in/num_sm;
|
|
|
|
float avg_rate_out = avail_out/num_sm;
|
|
|
|
|
|
|
|
float indiv_in = getMaxIndivRate(true);
|
|
|
|
float indiv_out = getMaxIndivRate(false);
|
|
|
|
|
|
|
|
float used_bw_in = 0;
|
|
|
|
float used_bw_out = 0;
|
|
|
|
|
|
|
|
float extra_bw_in = 0;
|
|
|
|
float extra_bw_out = 0;
|
|
|
|
|
|
|
|
int maxxed_in = 0;
|
|
|
|
int maxxed_out = 0;
|
|
|
|
|
|
|
|
// loop through modules....
|
|
|
|
for(it = mods.begin(); it != mods.end(); it++)
|
|
|
|
{
|
|
|
|
SearchModule *mod = (it -> second);
|
|
|
|
float crate_in = mod -> pqi -> getRate(true);
|
|
|
|
float crate_out = mod -> pqi -> getRate(false);
|
|
|
|
|
|
|
|
used_bw_in += crate_in;
|
|
|
|
used_bw_out += crate_out;
|
|
|
|
|
|
|
|
if (crate_in > avg_rate_in)
|
|
|
|
{
|
|
|
|
if (mod -> pqi -> getMaxRate(true) == indiv_in)
|
|
|
|
{
|
|
|
|
maxxed_in++;
|
|
|
|
}
|
|
|
|
extra_bw_in += crate_in - avg_rate_in;
|
|
|
|
}
|
|
|
|
if (crate_out > avg_rate_out)
|
|
|
|
{
|
|
|
|
if (mod -> pqi -> getMaxRate(false) == indiv_out)
|
|
|
|
{
|
|
|
|
maxxed_out++;
|
|
|
|
}
|
|
|
|
extra_bw_out += crate_out - avg_rate_out;
|
|
|
|
}
|
|
|
|
// std::cerr << "\tSM(" << mod -> smi << ")";
|
|
|
|
// std::cerr << "In A: " << mod -> pqi -> getMaxRate(true);
|
|
|
|
// std::cerr << " C: " << crate_in;
|
|
|
|
// std::cerr << " && Out A: " << mod -> pqi -> getMaxRate(false);
|
|
|
|
// std::cerr << " C: " << crate_out << std::endl;
|
|
|
|
}
|
|
|
|
// std::cerr << "Totals (In) Used B/W " << used_bw_in;
|
|
|
|
// std::cerr << " Excess B/W " << extra_bw_in;
|
|
|
|
// std::cerr << " Available B/W " << avail_in << std::endl;
|
|
|
|
// std::cerr << "Totals (Out) Used B/W " << used_bw_out;
|
|
|
|
// std::cerr << " Excess B/W " << extra_bw_out;
|
|
|
|
// std::cerr << " Available B/W " << avail_out << std::endl;
|
|
|
|
|
|
|
|
if (used_bw_in > avail_in)
|
|
|
|
{
|
|
|
|
//std::cerr << "Decreasing Incoming B/W!" << std::endl;
|
|
|
|
|
|
|
|
// drop all above the avg down!
|
|
|
|
float fchg = (used_bw_in - avail_in) / (float) extra_bw_in;
|
|
|
|
for(it = mods.begin(); it != mods.end(); it++)
|
|
|
|
{
|
|
|
|
SearchModule *mod = (it -> second);
|
|
|
|
float crate_in = mod -> pqi -> getRate(true);
|
|
|
|
float new_max = avg_rate_in;
|
|
|
|
if (crate_in > avg_rate_in)
|
|
|
|
{
|
|
|
|
new_max = avg_rate_in + (1 - fchg) *
|
|
|
|
(crate_in - avg_rate_in);
|
|
|
|
}
|
|
|
|
if (new_max > indiv_in)
|
|
|
|
{
|
|
|
|
new_max = indiv_in;
|
|
|
|
}
|
|
|
|
mod -> pqi -> setMaxRate(true, new_max);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// if not maxxed already and using less than 95%
|
|
|
|
else if ((maxxed_in != num_sm) && (used_bw_in < 0.95 * avail_in))
|
|
|
|
{
|
|
|
|
//std::cerr << "Increasing Incoming B/W!" << std::endl;
|
|
|
|
|
|
|
|
// increase.
|
|
|
|
float fchg = (avail_in - used_bw_in) / avail_in;
|
|
|
|
for(it = mods.begin(); it != mods.end(); it++)
|
|
|
|
{
|
|
|
|
SearchModule *mod = (it -> second);
|
|
|
|
float crate_in = mod -> pqi -> getRate(true);
|
|
|
|
float max_in = mod -> pqi -> getMaxRate(true);
|
|
|
|
|
|
|
|
if (max_in == indiv_in)
|
|
|
|
{
|
|
|
|
// do nothing...
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
float new_max = max_in;
|
|
|
|
if (max_in < avg_rate_in)
|
|
|
|
{
|
|
|
|
new_max = avg_rate_in * (1 + fchg);
|
|
|
|
}
|
|
|
|
else if (crate_in > 0.5 * max_in)
|
|
|
|
{
|
|
|
|
new_max = max_in * (1 + fchg);
|
|
|
|
}
|
|
|
|
if (new_max > indiv_in)
|
|
|
|
{
|
|
|
|
new_max = indiv_in;
|
|
|
|
}
|
|
|
|
mod -> pqi -> setMaxRate(true, new_max);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (used_bw_out > avail_out)
|
|
|
|
{
|
|
|
|
//std::cerr << "Decreasing Outgoing B/W!" << std::endl;
|
|
|
|
// drop all above the avg down!
|
|
|
|
float fchg = (used_bw_out - avail_out) / (float) extra_bw_out;
|
|
|
|
for(it = mods.begin(); it != mods.end(); it++)
|
|
|
|
{
|
|
|
|
SearchModule *mod = (it -> second);
|
|
|
|
float crate_out = mod -> pqi -> getRate(false);
|
|
|
|
float new_max = avg_rate_out;
|
|
|
|
if (crate_out > avg_rate_out)
|
|
|
|
{
|
|
|
|
new_max = avg_rate_out + (1 - fchg) *
|
|
|
|
(crate_out - avg_rate_out);
|
|
|
|
}
|
|
|
|
if (new_max > indiv_out)
|
|
|
|
{
|
|
|
|
new_max = indiv_out;
|
|
|
|
}
|
|
|
|
mod -> pqi -> setMaxRate(false, new_max);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// if not maxxed already and using less than 95%
|
|
|
|
else if ((maxxed_out != num_sm) && (used_bw_out < 0.95 * avail_out))
|
|
|
|
{
|
|
|
|
//std::cerr << "Increasing Outgoing B/W!" << std::endl;
|
|
|
|
// increase.
|
|
|
|
float fchg = (avail_out - used_bw_out) / avail_out;
|
|
|
|
for(it = mods.begin(); it != mods.end(); it++)
|
|
|
|
{
|
|
|
|
SearchModule *mod = (it -> second);
|
|
|
|
float crate_out = mod -> pqi -> getRate(false);
|
|
|
|
float max_out = mod -> pqi -> getMaxRate(false);
|
|
|
|
|
|
|
|
if (max_out == indiv_out)
|
|
|
|
{
|
|
|
|
// do nothing...
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
float new_max = max_out;
|
|
|
|
if (max_out < avg_rate_out)
|
|
|
|
{
|
|
|
|
new_max = avg_rate_out * (1 + fchg);
|
|
|
|
}
|
|
|
|
else if (crate_out > 0.5 * max_out)
|
|
|
|
{
|
|
|
|
new_max = max_out * (1 + fchg);
|
|
|
|
}
|
|
|
|
if (new_max > indiv_out)
|
|
|
|
{
|
|
|
|
new_max = indiv_out;
|
|
|
|
}
|
|
|
|
mod -> pqi -> setMaxRate(false, new_max);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|