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"
|
|
|
|
|
2008-07-10 12:29:18 -04:00
|
|
|
#include "util/rsdebug.h"
|
2012-04-13 20:30:23 -04:00
|
|
|
#include "util/rsstring.h"
|
2009-06-08 13:09:00 -04:00
|
|
|
#include <stdlib.h>
|
2013-10-21 07:00:49 -04:00
|
|
|
#include <time.h>
|
2015-12-23 09:49:05 -05:00
|
|
|
|
|
|
|
using std::dec;
|
|
|
|
|
|
|
|
#include <time.h>
|
|
|
|
#include <sys/time.h>
|
|
|
|
#ifdef WINDOWS_SYS
|
|
|
|
#include <sys/timeb.h>
|
|
|
|
#endif
|
|
|
|
|
2015-12-29 23:39:52 -05:00
|
|
|
//#define PQI_HDL_DEBUG_UR 1
|
|
|
|
|
|
|
|
#ifdef PQI_HDL_DEBUG_UR
|
2015-12-23 09:49:05 -05:00
|
|
|
static double getCurrentTS()
|
|
|
|
{
|
|
|
|
|
|
|
|
#ifndef WINDOWS_SYS
|
|
|
|
struct timeval cts_tmp;
|
|
|
|
gettimeofday(&cts_tmp, NULL);
|
|
|
|
double cts = (cts_tmp.tv_sec) + ((double) cts_tmp.tv_usec) / 1000000.0;
|
|
|
|
#else
|
|
|
|
struct _timeb timebuf;
|
|
|
|
_ftime( &timebuf);
|
|
|
|
double cts = (timebuf.time) + ((double) timebuf.millitm) / 1000.0;
|
|
|
|
#endif
|
|
|
|
return cts;
|
|
|
|
}
|
2015-12-29 23:39:52 -05:00
|
|
|
#endif
|
2015-12-23 09:49:05 -05:00
|
|
|
|
2007-11-14 22:18:48 -05:00
|
|
|
const int pqihandlerzone = 34283;
|
|
|
|
|
2011-09-04 16:01:30 -04:00
|
|
|
static const int PQI_HANDLER_NB_PRIORITY_LEVELS = 10 ;
|
|
|
|
static const float PQI_HANDLER_NB_PRIORITY_RATIO = 2 ;
|
|
|
|
|
2008-04-03 08:51:28 -04:00
|
|
|
/****
|
|
|
|
#define DEBUG_TICK 1
|
|
|
|
#define RSITEM_DEBUG 1
|
|
|
|
****/
|
2007-11-14 22:18:48 -05:00
|
|
|
|
2015-06-17 04:49:43 -04:00
|
|
|
pqihandler::pqihandler() : coreMtx("pqihandler")
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
2008-11-22 08:15:07 -05:00
|
|
|
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
|
|
|
|
|
2007-11-14 22:18:48 -05:00
|
|
|
// setup minimal total+individual rates.
|
|
|
|
rateIndiv_out = 0.01;
|
|
|
|
rateIndiv_in = 0.01;
|
|
|
|
rateMax_out = 0.01;
|
2015-04-19 16:03:46 -04:00
|
|
|
rateMax_in = 0.01;
|
|
|
|
rateTotal_in = 0.0 ;
|
|
|
|
rateTotal_out = 0.0 ;
|
|
|
|
last_m = time(NULL) ;
|
2011-09-04 16:01:30 -04:00
|
|
|
nb_ticks = 0 ;
|
|
|
|
ticks_per_sec = 5 ; // initial guess
|
2015-04-19 16:03:46 -04:00
|
|
|
return;
|
2007-11-14 22:18:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
int pqihandler::tick()
|
|
|
|
{
|
2008-11-22 08:15:07 -05:00
|
|
|
int moreToTick = 0;
|
|
|
|
|
2015-12-23 09:49:05 -05:00
|
|
|
{
|
2011-09-04 16:01:30 -04:00
|
|
|
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
|
2008-11-22 08:15:07 -05:00
|
|
|
|
2011-09-04 16:01:30 -04:00
|
|
|
// tick all interfaces...
|
2014-03-17 16:56:06 -04:00
|
|
|
std::map<RsPeerId, SearchModule *>::iterator it;
|
2014-10-24 18:07:26 -04:00
|
|
|
for(it = mods.begin(); it != mods.end(); ++it)
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
2011-09-04 16:01:30 -04:00
|
|
|
if (0 < ((it -> second) -> pqi) -> tick())
|
|
|
|
{
|
2008-04-03 08:51:28 -04:00
|
|
|
#ifdef DEBUG_TICK
|
2011-09-04 16:01:30 -04:00
|
|
|
std::cerr << "pqihandler::tick() moreToTick from mod()" << std::endl;
|
2008-04-03 08:51:28 -04:00
|
|
|
#endif
|
2011-09-04 16:01:30 -04:00
|
|
|
moreToTick = 1;
|
|
|
|
}
|
2007-11-14 22:18:48 -05:00
|
|
|
}
|
2015-04-24 05:29:40 -04:00
|
|
|
#ifdef TO_BE_REMOVED
|
2011-09-04 16:01:30 -04:00
|
|
|
// get the items, and queue them correctly
|
|
|
|
if (0 < locked_GetItems())
|
|
|
|
{
|
2008-04-03 08:51:28 -04:00
|
|
|
#ifdef DEBUG_TICK
|
2011-09-04 16:01:30 -04:00
|
|
|
std::cerr << "pqihandler::tick() moreToTick from GetItems()" << std::endl;
|
2008-04-03 08:51:28 -04:00
|
|
|
#endif
|
2011-09-04 16:01:30 -04:00
|
|
|
moreToTick = 1;
|
|
|
|
}
|
2015-04-24 05:29:40 -04:00
|
|
|
#endif
|
2014-10-31 17:24:42 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// static time_t last_print_time = 0 ;
|
|
|
|
// time_t now = time(NULL) ;
|
|
|
|
// if(now > last_print_time + 3)
|
|
|
|
// {
|
|
|
|
// std::map<uint16_t,uint32_t> per_service_count ;
|
|
|
|
// std::vector<uint32_t> per_priority_count ;
|
|
|
|
//
|
|
|
|
// ExtractOutQueueStatistics(per_service_count,per_priority_count) ;
|
|
|
|
//
|
|
|
|
// std::cerr << "PQIHandler outqueues: " << std::endl;
|
|
|
|
//
|
|
|
|
// for(std::map<uint16_t,uint32_t>::const_iterator it=per_service_count.begin();it!=per_service_count.end();++it)
|
|
|
|
// std::cerr << " " << std::hex << it->first << std::dec << " " << it->second << std::endl;
|
|
|
|
//
|
|
|
|
// for(int i=0;i<per_priority_count.size();++i)
|
|
|
|
// std::cerr << " " << i << " : " << per_priority_count[i] << std::endl;
|
|
|
|
//
|
|
|
|
// last_print_time = now ;
|
|
|
|
// }
|
2011-09-04 16:01:30 -04:00
|
|
|
|
2007-11-14 22:18:48 -05:00
|
|
|
UpdateRates();
|
|
|
|
return moreToTick;
|
|
|
|
}
|
|
|
|
|
2011-09-04 16:01:30 -04:00
|
|
|
|
|
|
|
bool pqihandler::queueOutRsItem(RsItem *item)
|
|
|
|
{
|
|
|
|
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
|
2012-06-23 08:10:41 -04:00
|
|
|
|
|
|
|
uint32_t size ;
|
2015-06-17 05:07:45 -04:00
|
|
|
locked_HandleRsItem(item, size);
|
2011-09-04 16:01:30 -04:00
|
|
|
|
|
|
|
#ifdef DEBUG_QOS
|
|
|
|
if(item->priority_level() == QOS_PRIORITY_UNKNOWN)
|
|
|
|
std::cerr << "Caught an unprioritized item !" << std::endl;
|
|
|
|
|
|
|
|
print() ;
|
|
|
|
#endif
|
|
|
|
return true ;
|
|
|
|
}
|
2007-11-14 22:18:48 -05:00
|
|
|
|
|
|
|
int pqihandler::status()
|
|
|
|
{
|
2014-03-17 16:56:06 -04:00
|
|
|
std::map<RsPeerId, SearchModule *>::iterator it;
|
2008-11-22 08:15:07 -05:00
|
|
|
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
|
2007-11-14 22:18:48 -05:00
|
|
|
|
|
|
|
{ // for output
|
2012-04-13 20:30:23 -04:00
|
|
|
std::string out = "pqihandler::status() Active Modules:\n";
|
2007-11-14 22:18:48 -05:00
|
|
|
|
2012-04-13 20:30:23 -04:00
|
|
|
// display all interfaces...
|
2014-10-24 18:07:26 -04:00
|
|
|
for(it = mods.begin(); it != mods.end(); ++it)
|
2012-04-13 20:30:23 -04:00
|
|
|
{
|
2014-03-17 16:56:06 -04:00
|
|
|
rs_sprintf_append(out, "\tModule [%s] Pointer <%p>", it -> first.toStdString().c_str(), (void *) ((it -> second) -> pqi));
|
2012-04-13 20:30:23 -04:00
|
|
|
}
|
2007-11-14 22:18:48 -05:00
|
|
|
|
2012-04-13 20:30:23 -04:00
|
|
|
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, out);
|
2007-11-14 22:18:48 -05:00
|
|
|
|
|
|
|
} // end of output.
|
|
|
|
|
|
|
|
|
|
|
|
// status all interfaces...
|
2014-10-24 18:07:26 -04:00
|
|
|
for(it = mods.begin(); it != mods.end(); ++it)
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
|
|
|
((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
|
|
|
{
|
2010-01-14 17:50:27 -05:00
|
|
|
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
|
2007-12-11 20:29:14 -05:00
|
|
|
// if peerid used -> error.
|
2014-03-17 16:56:06 -04:00
|
|
|
std::map<RsPeerId, SearchModule *>::iterator it;
|
2007-12-11 20:29:14 -05:00
|
|
|
if (mod->peerid != mod->pqi->PeerId())
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
2007-12-11 20:29:14 -05:00
|
|
|
// ERROR!
|
2012-04-13 20:30:23 -04:00
|
|
|
pqioutput(PQL_ALERT, pqihandlerzone, "ERROR peerid != PeerId!");
|
2007-12-11 20:29:14 -05:00
|
|
|
return false;
|
2007-11-14 22:18:48 -05:00
|
|
|
}
|
2007-12-11 20:29:14 -05:00
|
|
|
|
2014-03-17 16:56:06 -04:00
|
|
|
if (mod->peerid.isNull())
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
2007-12-11 20:29:14 -05:00
|
|
|
// ERROR!
|
2012-04-13 20:30:23 -04:00
|
|
|
pqioutput(PQL_ALERT, pqihandlerzone, "ERROR peerid == NULL");
|
2007-12-11 20:29:14 -05:00
|
|
|
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!
|
2012-04-13 20:30:23 -04:00
|
|
|
pqioutput(PQL_ALERT, pqihandlerzone, "ERROR PeerId Module already exists!");
|
2007-12-11 20:29:14 -05:00
|
|
|
return false;
|
2007-11-14 22:18:48 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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
|
|
|
{
|
2008-11-22 08:15:07 -05:00
|
|
|
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
|
2014-03-17 16:56:06 -04:00
|
|
|
std::map<RsPeerId, SearchModule *>::iterator it;
|
2014-10-24 18:07:26 -04:00
|
|
|
for(it = mods.begin(); it != mods.end(); ++it)
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
// generalised output
|
2015-06-17 05:07:45 -04:00
|
|
|
int pqihandler::locked_HandleRsItem(RsItem *item, uint32_t& computed_size)
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
2011-09-04 16:01:30 -04:00
|
|
|
computed_size = 0 ;
|
2014-03-17 16:56:06 -04:00
|
|
|
std::map<RsPeerId, SearchModule *>::iterator it;
|
2015-12-23 09:49:05 -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
|
|
|
|
2015-12-23 09:49:05 -05:00
|
|
|
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone,
|
2007-12-11 20:29:14 -05:00
|
|
|
"pqihandler::HandleRsItem() Sending to One Channel");
|
2009-12-13 16:59:26 -05:00
|
|
|
#ifdef DEBUG_TICK
|
|
|
|
std::cerr << "pqihandler::HandleRsItem() Sending to One Channel" << std::endl;
|
|
|
|
#endif
|
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())
|
|
|
|
{
|
2012-04-13 20:30:23 -04:00
|
|
|
std::string out = "pqihandler::HandleRsItem() Invalid chan!";
|
|
|
|
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, out);
|
2009-12-13 16:59:26 -05:00
|
|
|
#ifdef DEBUG_TICK
|
2012-04-13 20:30:23 -04:00
|
|
|
std::cerr << out << std::endl;
|
2009-12-13 16:59:26 -05:00
|
|
|
#endif
|
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
|
|
|
|
2014-03-17 16:56:06 -04:00
|
|
|
std::string out = "pqihandler::HandleRsItem() sending to chan: " + it -> first.toStdString();
|
2012-04-13 20:30:23 -04:00
|
|
|
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, out);
|
2009-12-13 16:59:26 -05:00
|
|
|
#ifdef DEBUG_TICK
|
2012-04-13 20:30:23 -04:00
|
|
|
std::cerr << out << std::endl;
|
2009-12-13 16:59:26 -05:00
|
|
|
#endif
|
2007-11-14 22:18:48 -05:00
|
|
|
|
2007-12-11 20:29:14 -05:00
|
|
|
// if yes send on item.
|
2011-09-04 16:01:30 -04:00
|
|
|
((it -> second) -> pqi) -> SendItem(item,computed_size);
|
2007-12-11 20:29:14 -05:00
|
|
|
return 1;
|
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
|
|
|
{
|
2011-09-04 16:01:30 -04:00
|
|
|
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, "pqihandler::SendRsRawItem()");
|
|
|
|
|
2012-06-23 08:10:41 -04:00
|
|
|
// directly send item to streamers
|
2015-12-23 09:49:05 -05:00
|
|
|
|
2011-09-04 16:01:30 -04:00
|
|
|
return queueOutRsItem(ns) ;
|
2007-11-14 22:18:48 -05:00
|
|
|
}
|
|
|
|
|
2015-04-24 05:29:40 -04:00
|
|
|
#ifdef TO_BE_REMOVED
|
|
|
|
|
2007-11-14 22:18:48 -05:00
|
|
|
// inputs. This is a very basic
|
|
|
|
// system that is completely biased and slow...
|
|
|
|
// someone please fix.
|
|
|
|
|
2014-03-21 23:53:44 -04:00
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
// THIS CODE SHOULD BE ABLE TO BE REMOVED!
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2008-11-22 08:15:07 -05:00
|
|
|
int pqihandler::locked_GetItems()
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
2014-03-17 16:56:06 -04:00
|
|
|
std::map<RsPeerId, 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....
|
2014-10-24 18:07:26 -04:00
|
|
|
for(it = mods.begin(); it != mods.end(); ++it)
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
|
|
|
SearchModule *mod = (it -> second);
|
|
|
|
|
|
|
|
// check security... is output allowed.
|
2015-12-23 09:49:05 -05:00
|
|
|
if(0 < secpolicy_check((it -> second) -> sp,
|
2008-02-07 11:18:34 -05:00
|
|
|
0, PQI_INCOMING)) // PQI_ITEM_TYPE_ITEM, PQI_INCOMING))
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
|
|
|
// if yes... attempt to read.
|
|
|
|
while((item = (mod -> pqi) -> GetItem()) != NULL)
|
|
|
|
{
|
2014-03-21 23:53:44 -04:00
|
|
|
|
2014-10-31 17:24:42 -04:00
|
|
|
static int ntimes =0 ;
|
2015-04-23 17:37:16 -04:00
|
|
|
// if(++ntimes < 20)
|
2014-10-31 17:24:42 -04:00
|
|
|
{
|
2014-03-21 23:53:44 -04:00
|
|
|
std::cerr << "pqihandler::locked_GetItems() pqi->GetItem()";
|
2015-04-23 15:31:41 -04:00
|
|
|
std::cerr << " should never happen anymore!";
|
|
|
|
std::cerr << std::endl;
|
2014-10-31 17:24:42 -04:00
|
|
|
}
|
2014-03-21 23:53:44 -04:00
|
|
|
|
2015-12-23 09:49:05 -05:00
|
|
|
#ifdef RSITEM_DEBUG
|
2012-04-13 20:30:23 -04:00
|
|
|
std::string out;
|
|
|
|
rs_sprintf(out, "pqihandler::GetItems() Incoming Item from: %p\n", mod -> pqi);
|
|
|
|
item -> print_string(out);
|
2007-11-14 22:18:48 -05:00
|
|
|
|
2015-12-23 09:49:05 -05:00
|
|
|
pqioutput(PQL_DEBUG_BASIC,
|
2012-04-13 20:30:23 -04:00
|
|
|
pqihandlerzone, out);
|
2008-04-03 08:51:28 -04:00
|
|
|
#endif
|
2007-11-14 22:18:48 -05:00
|
|
|
|
2007-12-11 20:29:14 -05:00
|
|
|
if (item->PeerId() != (mod->pqi)->PeerId())
|
|
|
|
{
|
|
|
|
/* ERROR */
|
2015-12-23 09:49:05 -05:00
|
|
|
pqioutput(PQL_ALERT,
|
2007-12-11 20:29:14 -05:00
|
|
|
pqihandlerzone, "ERROR PeerIds dont match!");
|
|
|
|
item->PeerId(mod->pqi->PeerId());
|
|
|
|
}
|
|
|
|
|
2008-11-22 08:15:07 -05:00
|
|
|
locked_SortnStoreItem(item);
|
2007-11-14 22:18:48 -05:00
|
|
|
count++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// not allowed to recieve from here....
|
|
|
|
while((item = (mod -> pqi) -> GetItem()) != NULL)
|
|
|
|
{
|
2012-04-13 20:30:23 -04:00
|
|
|
std::string out;
|
|
|
|
rs_sprintf(out, "pqihandler::GetItems() Incoming Item from: %p\n", mod -> pqi);
|
|
|
|
item -> print_string(out);
|
|
|
|
out += "\nItem Not Allowed (Sec Pol). deleting!";
|
2007-11-14 22:18:48 -05:00
|
|
|
|
2012-04-13 20:30:23 -04:00
|
|
|
pqioutput(PQL_DEBUG_BASIC,
|
|
|
|
pqihandlerzone, out);
|
2007-11-14 22:18:48 -05:00
|
|
|
|
|
|
|
delete item;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
2008-11-22 08:15:07 -05:00
|
|
|
void pqihandler::locked_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();
|
|
|
|
|
|
|
|
/* whole Version reserved for SERVICES/CACHES */
|
|
|
|
if (vers == RS_PKT_VERSION_SERVICE)
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
2015-12-23 09:49:05 -05:00
|
|
|
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone,
|
2007-12-11 20:29:14 -05:00
|
|
|
"SortnStore -> Service");
|
|
|
|
in_service.push_back(item);
|
|
|
|
item = NULL;
|
|
|
|
return;
|
2007-11-14 22:18:48 -05:00
|
|
|
}
|
2013-10-01 04:11:15 -04:00
|
|
|
std::cerr << "pqihandler::locked_SortnStoreItem() : unhandled item! Will be deleted. This is certainly a bug." << std::endl;
|
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
|
|
|
{
|
2013-10-01 04:11:15 -04:00
|
|
|
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, "SortnStore -> Invalid VERSION! Deleting!");
|
2007-12-11 20:29:14 -05:00
|
|
|
delete item;
|
|
|
|
item = NULL;
|
|
|
|
return;
|
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
|
|
|
{
|
2013-10-01 04:11:15 -04:00
|
|
|
pqioutput(PQL_DEBUG_BASIC, pqihandlerzone, "SortnStore -> Deleting Unsorted Item");
|
2007-12-11 20:29:14 -05:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2007-12-11 20:29:14 -05:00
|
|
|
RsRawItem *pqihandler::GetRsRawItem()
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
2008-11-22 08:15:07 -05:00
|
|
|
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2014-03-21 23:53:44 -04:00
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
// ABOVE CODE SHOULD BE ABLE TO BE REMOVED!
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2015-04-24 05:29:40 -04:00
|
|
|
#endif
|
2014-03-21 23:53:44 -04:00
|
|
|
|
2007-11-14 22:18:48 -05:00
|
|
|
static const float MIN_RATE = 0.01; // 10 B/s
|
|
|
|
|
2015-07-12 00:04:18 -04:00
|
|
|
int pqihandler::ExtractTrafficInfo(std::list<RSTrafficClue>& out_lst,std::list<RSTrafficClue>& in_lst)
|
|
|
|
{
|
|
|
|
in_lst.clear() ;
|
|
|
|
out_lst.clear() ;
|
|
|
|
|
|
|
|
for( std::map<RsPeerId, SearchModule *>::iterator it = mods.begin(); it != mods.end(); ++it)
|
2015-07-17 16:13:31 -04:00
|
|
|
{
|
|
|
|
std::list<RSTrafficClue> ilst,olst ;
|
|
|
|
|
|
|
|
(it -> second)->pqi->gatherStatistics(olst,ilst) ;
|
|
|
|
|
|
|
|
for(std::list<RSTrafficClue>::const_iterator it(ilst.begin());it!=ilst.end();++it) in_lst.push_back(*it) ;
|
|
|
|
for(std::list<RSTrafficClue>::const_iterator it(olst.begin());it!=olst.end();++it) out_lst.push_back(*it) ;
|
|
|
|
}
|
2015-07-12 00:04:18 -04:00
|
|
|
|
|
|
|
return 1 ;
|
|
|
|
}
|
|
|
|
|
2012-06-21 19:23:46 -04:00
|
|
|
// NEW extern fn to extract rates.
|
2014-03-17 16:56:06 -04:00
|
|
|
int pqihandler::ExtractRates(std::map<RsPeerId, RsBwRates> &ratemap, RsBwRates &total)
|
2012-06-21 19:23:46 -04:00
|
|
|
{
|
|
|
|
total.mMaxRateIn = getMaxRate(true);
|
|
|
|
total.mMaxRateOut = getMaxRate(false);
|
|
|
|
total.mRateIn = 0;
|
|
|
|
total.mRateOut = 0;
|
2012-06-21 21:35:32 -04:00
|
|
|
total.mQueueIn = 0;
|
|
|
|
total.mQueueOut = 0;
|
2012-06-21 19:23:46 -04:00
|
|
|
|
|
|
|
/* Lock once rates have been retrieved */
|
|
|
|
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
|
|
|
|
|
2014-03-17 16:56:06 -04:00
|
|
|
std::map<RsPeerId, SearchModule *>::iterator it;
|
2014-10-24 18:07:26 -04:00
|
|
|
for(it = mods.begin(); it != mods.end(); ++it)
|
2012-06-21 19:23:46 -04:00
|
|
|
{
|
|
|
|
SearchModule *mod = (it -> second);
|
|
|
|
|
|
|
|
RsBwRates peerRates;
|
|
|
|
mod -> pqi -> getRates(peerRates);
|
|
|
|
|
|
|
|
total.mRateIn += peerRates.mRateIn;
|
|
|
|
total.mRateOut += peerRates.mRateOut;
|
2012-06-21 21:35:32 -04:00
|
|
|
total.mQueueIn += peerRates.mQueueIn;
|
|
|
|
total.mQueueOut += peerRates.mQueueOut;
|
2012-06-21 19:23:46 -04:00
|
|
|
|
|
|
|
ratemap[it->first] = peerRates;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2015-12-23 09:49:05 -05:00
|
|
|
// internal fn to send updates
|
2007-11-14 22:18:48 -05:00
|
|
|
int pqihandler::UpdateRates()
|
|
|
|
{
|
2015-12-23 09:49:05 -05:00
|
|
|
#ifdef PQI_HDL_DEBUG_UR
|
|
|
|
uint64_t t_now;
|
|
|
|
#endif
|
|
|
|
|
2014-03-17 16:56:06 -04:00
|
|
|
std::map<RsPeerId, SearchModule *>::iterator it;
|
2015-12-23 09:49:05 -05:00
|
|
|
|
2007-11-14 22:18:48 -05:00
|
|
|
int num_sm = mods.size();
|
|
|
|
|
|
|
|
float avail_in = getMaxRate(true);
|
|
|
|
float avail_out = getMaxRate(false);
|
|
|
|
|
|
|
|
float used_bw_in = 0;
|
|
|
|
float used_bw_out = 0;
|
2015-12-23 09:49:05 -05:00
|
|
|
float used_bw_in_table[num_sm]; /* table of in bandwidth currently used by each module */
|
|
|
|
float used_bw_out_table[num_sm]; /* table of out bandwidth currently used by each module */
|
2007-11-14 22:18:48 -05:00
|
|
|
|
2008-11-22 08:15:07 -05:00
|
|
|
/* Lock once rates have been retrieved */
|
|
|
|
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
|
|
|
|
|
2009-06-08 13:09:00 -04:00
|
|
|
int effectiveUploadsSm = 0;
|
|
|
|
int effectiveDownloadsSm = 0;
|
2015-12-23 09:49:05 -05:00
|
|
|
|
2009-06-08 13:09:00 -04:00
|
|
|
// loop through modules to get the used bandwith and the number of modules that are affectively transfering
|
2015-12-23 09:49:05 -05:00
|
|
|
#ifdef PQI_HDL_DEBUG_UR
|
|
|
|
std::cerr << " Looping through modules" << std::endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
int index = 0;
|
|
|
|
|
2014-10-24 18:07:26 -04:00
|
|
|
for(it = mods.begin(); it != mods.end(); ++it)
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
|
|
|
SearchModule *mod = (it -> second);
|
|
|
|
float crate_in = mod -> pqi -> getRate(true);
|
2015-12-23 09:49:05 -05:00
|
|
|
if ((crate_in > 0.01 * avail_in) || (crate_in > 0.1))
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
2014-10-21 18:33:02 -04:00
|
|
|
++effectiveDownloadsSm;
|
2007-11-14 22:18:48 -05:00
|
|
|
}
|
|
|
|
|
2009-06-08 13:09:00 -04:00
|
|
|
float crate_out = mod -> pqi -> getRate(false);
|
2015-12-23 09:49:05 -05:00
|
|
|
if ((crate_out > 0.01 * avail_out) || (crate_out > 0.1))
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
2014-10-21 18:33:02 -04:00
|
|
|
++effectiveUploadsSm;
|
2007-11-14 22:18:48 -05:00
|
|
|
}
|
2009-06-08 13:09:00 -04:00
|
|
|
|
|
|
|
used_bw_in += crate_in;
|
|
|
|
used_bw_out += crate_out;
|
2015-12-23 09:49:05 -05:00
|
|
|
|
|
|
|
/* fill the table of bandwidth */
|
|
|
|
used_bw_in_table[index] = crate_in;
|
|
|
|
used_bw_out_table[index] = crate_out;
|
|
|
|
++index;
|
2007-11-14 22:18:48 -05:00
|
|
|
}
|
2015-12-23 09:49:05 -05:00
|
|
|
|
|
|
|
#ifdef PQI_HDL_DEBUG_UR
|
|
|
|
t_now = 1000 * getCurrentTS();
|
|
|
|
std::cerr << dec << t_now << " pqihandler::UpdateRates(): Sorting used_bw_out_table: " << num_sm << " entries" << std::endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Sort the used bw in/out table in ascending order */
|
|
|
|
std::sort(used_bw_in_table, used_bw_in_table + num_sm);
|
|
|
|
std::sort(used_bw_out_table, used_bw_out_table + num_sm);
|
|
|
|
|
|
|
|
#ifdef PQI_HDL_DEBUG_UR
|
|
|
|
t_now = 1000 * getCurrentTS();
|
|
|
|
std::cerr << dec << t_now << " pqihandler::UpdateRates(): Done." << std::endl;
|
|
|
|
std::cerr << dec << t_now << " pqihandler::UpdateRates(): used_bw_out " << used_bw_out << std::endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Calculate the optimal out_max value, taking into account avail_out and the out bw requested by modules */
|
|
|
|
|
|
|
|
float out_remaining_bw = avail_out;
|
|
|
|
float out_max_bw = 0;
|
|
|
|
bool keep_going = true;
|
|
|
|
int mod_index = 0;
|
|
|
|
|
|
|
|
while (keep_going && (mod_index < num_sm)) {
|
|
|
|
float result = (num_sm - mod_index) * (used_bw_out_table[mod_index] - out_max_bw);
|
|
|
|
if (result > out_remaining_bw) {
|
|
|
|
/* There is not enough remaining out bw to satisfy all modules,
|
|
|
|
distribute the remaining out bw among modules, then exit */
|
|
|
|
out_max_bw += out_remaining_bw / (num_sm - mod_index);
|
|
|
|
out_remaining_bw = 0;
|
|
|
|
keep_going = false;
|
|
|
|
} else {
|
|
|
|
/* Grant the requested out bandwidth to all modules,
|
|
|
|
then recalculate the remaining out bandwidth */
|
|
|
|
out_remaining_bw -= result;
|
|
|
|
out_max_bw = used_bw_out_table[mod_index];
|
|
|
|
++mod_index;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef PQI_HDL_DEBUG_UR
|
|
|
|
t_now = 1000 * getCurrentTS();
|
|
|
|
std::cerr << dec << t_now << " pqihandler::UpdateRates(): mod_index " << mod_index << " out_max_bw " << out_max_bw << " remaining out bw " << out_remaining_bw << std::endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Allocate only half the remaining out bw, if any, to make it smoother */
|
|
|
|
out_max_bw = out_max_bw + out_remaining_bw / 2;
|
|
|
|
|
|
|
|
/* Calculate the optimal in_max value, taking into account avail_in and the in bw requested by modules */
|
|
|
|
|
|
|
|
float in_remaining_bw = avail_in;
|
|
|
|
float in_max_bw = 0;
|
|
|
|
keep_going = true;
|
|
|
|
mod_index = 0;
|
|
|
|
|
|
|
|
while (keep_going && mod_index < num_sm) {
|
|
|
|
float result = (num_sm - mod_index) * (used_bw_in_table[mod_index] - in_max_bw);
|
|
|
|
if (result > in_remaining_bw) {
|
|
|
|
/* There is not enough remaining in bw to satisfy all modules,
|
|
|
|
distribute the remaining in bw among modules, then exit */
|
|
|
|
in_max_bw += in_remaining_bw / (num_sm - mod_index);
|
|
|
|
in_remaining_bw = 0;
|
|
|
|
keep_going = false;
|
|
|
|
} else {
|
|
|
|
/* Grant the requested in bandwidth to all modules,
|
|
|
|
then recalculate the remaining in bandwidth */
|
|
|
|
in_remaining_bw -= result;
|
|
|
|
in_max_bw = used_bw_in_table[mod_index];
|
|
|
|
++mod_index;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef PQI_HDL_DEBUG_UR
|
|
|
|
t_now = 1000 * getCurrentTS();
|
|
|
|
std::cerr << dec << t_now << " pqihandler::UpdateRates(): mod_index " << mod_index << " in_max_bw " << in_max_bw << " remaining in bw " << in_remaining_bw << std::endl;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Allocate only half the remaining in bw, if any, to make it smoother */
|
|
|
|
in_max_bw = in_max_bw + in_remaining_bw / 2;
|
|
|
|
|
|
|
|
|
2011-09-04 16:01:30 -04:00
|
|
|
#ifdef DEBUG_QOS
|
2009-06-08 13:09:00 -04:00
|
|
|
// std::cerr << "Totals (In) Used B/W " << used_bw_in;
|
|
|
|
// std::cerr << " Available B/W " << avail_in;
|
|
|
|
// std::cerr << " Effective transfers " << effectiveDownloadsSm << std::endl;
|
|
|
|
// std::cerr << "Totals (Out) Used B/W " << used_bw_out;
|
|
|
|
// std::cerr << " Available B/W " << avail_out;
|
|
|
|
// std::cerr << " Effective transfers " << effectiveUploadsSm << std::endl;
|
2011-09-04 16:01:30 -04:00
|
|
|
#endif
|
2007-11-14 22:18:48 -05:00
|
|
|
|
2009-06-08 13:09:00 -04:00
|
|
|
locked_StoreCurrentRates(used_bw_in, used_bw_out);
|
2007-11-14 22:18:48 -05:00
|
|
|
|
2009-06-08 13:09:00 -04:00
|
|
|
//computing average rates for effective transfers
|
|
|
|
float max_in_effective = avail_in / num_sm;
|
|
|
|
if (effectiveDownloadsSm != 0) {
|
|
|
|
max_in_effective = avail_in / effectiveDownloadsSm;
|
|
|
|
}
|
|
|
|
float max_out_effective = avail_out / num_sm;
|
|
|
|
if (effectiveUploadsSm != 0) {
|
|
|
|
max_out_effective = avail_out / effectiveUploadsSm;
|
|
|
|
}
|
2007-11-14 22:18:48 -05:00
|
|
|
|
2015-12-23 09:49:05 -05:00
|
|
|
//modify the in and out limit
|
|
|
|
#ifdef PQI_HDL_DEBUG_UR
|
|
|
|
t_now = 1000 * getCurrentTS();
|
|
|
|
std::cerr << dec << t_now << " pqihandler::UpdateRates(): setting new out_max " << out_max_bw << " in_max " << in_max_bw << std::endl;
|
|
|
|
#endif
|
2007-11-14 22:18:48 -05:00
|
|
|
|
2015-12-23 09:49:05 -05:00
|
|
|
for(it = mods.begin(); it != mods.end(); ++it)
|
|
|
|
{
|
|
|
|
SearchModule *mod = (it -> second);
|
|
|
|
mod -> pqi -> setMaxRate(true, in_max_bw);
|
|
|
|
mod -> pqi -> setMaxRate(false, out_max_bw);
|
2009-06-08 13:09:00 -04:00
|
|
|
}
|
2007-11-14 22:18:48 -05:00
|
|
|
|
2015-12-23 09:49:05 -05:00
|
|
|
|
2009-06-08 13:09:00 -04:00
|
|
|
//cap the rates
|
2014-10-24 18:07:26 -04:00
|
|
|
for(it = mods.begin(); it != mods.end(); ++it)
|
2007-11-14 22:18:48 -05:00
|
|
|
{
|
2009-06-08 13:09:00 -04:00
|
|
|
SearchModule *mod = (it -> second);
|
|
|
|
if (mod -> pqi -> getMaxRate(false) < max_out_effective) {
|
2015-12-23 09:49:05 -05:00
|
|
|
mod -> pqi -> setMaxRate(false, max_out_effective);
|
2007-11-14 22:18:48 -05:00
|
|
|
}
|
2009-06-08 13:09:00 -04:00
|
|
|
if (mod -> pqi -> getMaxRate(false) > avail_out) {
|
2015-12-23 09:49:05 -05:00
|
|
|
mod -> pqi -> setMaxRate(false, avail_out);
|
2009-06-08 13:09:00 -04:00
|
|
|
}
|
|
|
|
if (mod -> pqi -> getMaxRate(true) < max_in_effective) {
|
2015-12-23 09:49:05 -05:00
|
|
|
mod -> pqi -> setMaxRate(true, max_in_effective);
|
2009-06-08 13:09:00 -04:00
|
|
|
}
|
|
|
|
if (mod -> pqi -> getMaxRate(true) > avail_in) {
|
2015-12-23 09:49:05 -05:00
|
|
|
mod -> pqi -> setMaxRate(true, avail_in);
|
2007-11-14 22:18:48 -05:00
|
|
|
}
|
|
|
|
}
|
2008-06-09 20:47:24 -04:00
|
|
|
|
2007-11-14 22:18:48 -05:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2008-06-09 20:47:24 -04:00
|
|
|
void pqihandler::getCurrentRates(float &in, float &out)
|
|
|
|
{
|
2008-11-22 08:15:07 -05:00
|
|
|
RsStackMutex stack(coreMtx); /**************** LOCKED MUTEX ****************/
|
|
|
|
|
2008-06-09 20:47:24 -04:00
|
|
|
in = rateTotal_in;
|
|
|
|
out = rateTotal_out;
|
|
|
|
}
|
|
|
|
|
2008-11-22 08:15:07 -05:00
|
|
|
void pqihandler::locked_StoreCurrentRates(float in, float out)
|
2008-06-09 20:47:24 -04:00
|
|
|
{
|
|
|
|
rateTotal_in = in;
|
|
|
|
rateTotal_out = out;
|
|
|
|
}
|
|
|
|
|
2007-11-14 22:18:48 -05:00
|
|
|
|