<filters>
<filter id="frontend" type="frontend_net">
<port>@:9000</port>
+ <connect-max>3</connect-max>
</filter>
<filter id="backend" type="z3950_client">
</filter>
#include <yazpp/z-assoc.h>
#include <yazpp/pdu-assoc.h>
#include <yazpp/socket-manager.h>
+#include <yazpp/limit-connect.h>
#include <yaz/log.h>
#include <iostream>
std::vector<std::string> m_ports;
int m_listen_duration;
int m_session_timeout;
+ int m_connect_max;
yazpp_1::SocketManager mySocketManager;
-
ZAssocServer **az;
};
}
class ZAssocServer : public yazpp_1::Z_Assoc {
public:
~ZAssocServer();
- ZAssocServer(yazpp_1::IPDU_Observable *PDU_Observable, int timeout);
+ ZAssocServer(yazpp_1::IPDU_Observable *PDU_Observable, int timeout,
+ int connect_max);
void set_package(const mp::Package *package);
void set_thread_pool(ThreadPoolSocketObserver *m_thread_pool_observer);
private:
mp::ThreadPoolSocketObserver *m_thread_pool_observer;
const mp::Package *m_package;
int m_session_timeout;
+ int m_connect_max;
+ yazpp_1::LimitConnect limit_connect;
};
}
}
mp::ZAssocServer::ZAssocServer(yazpp_1::IPDU_Observable *PDU_Observable,
- int timeout)
- : Z_Assoc(PDU_Observable), m_session_timeout(timeout)
+ int timeout, int connect_max)
+ : Z_Assoc(PDU_Observable), m_session_timeout(timeout),
+ m_connect_max(connect_max)
{
m_package = 0;
}
yazpp_1::IPDU_Observer *mp::ZAssocServer::sessionNotify(yazpp_1::IPDU_Observable
*the_PDU_Observable, int fd)
{
+
+ const char *peername = the_PDU_Observable->getpeername();
+ if (peername)
+ {
+ limit_connect.add_connect(peername);
+ limit_connect.cleanup(false);
+ int con_sz = limit_connect.get_total(peername);
+ if (m_connect_max && con_sz > m_connect_max)
+ return 0;
+ }
mp::ZAssocChild *my =
new mp::ZAssocChild(the_PDU_Observable, m_thread_pool_observer,
m_package);
+ timeout_str);
m_p->m_session_timeout = timeout;
}
+ else if (!strcmp((const char *) ptr->name, "connect-max"))
+ {
+ m_p->m_connect_max = mp::xml::get_int(ptr->children, 0);
+ }
else
{
throw mp::filter::FilterException("Bad element "
// create ZAssoc with PDU Assoc
m_p->az[i] = new mp::ZAssocServer(as,
- m_p->m_session_timeout);
+ m_p->m_session_timeout,
+ m_p->m_connect_max);
if (m_p->az[i]->server(m_p->m_ports[i].c_str()))
{
throw mp::filter::FilterException("Unable to bind to address "
#include <time.h>
#include <yaz/log.h>
+#include <yazpp/bw.h>
#include "package.hpp"
#include "util.hpp"
namespace filter {
class Limit::Ses {
public:
- Yaz_bw bw_stat;
- Yaz_bw pdu_stat;
- Yaz_bw search_stat;
+ yazpp_1::Yaz_bw bw_stat;
+ yazpp_1::Yaz_bw pdu_stat;
+ yazpp_1::Yaz_bw search_stat;
Ses() : bw_stat(60), pdu_stat(60), search_stat(60) {};
};
+
class Limit::Impl {
public:
Impl();
void process(metaproxy_1::Package & package);
void configure(const xmlNode * ptr);
private:
-
boost::mutex m_session_mutex;
std::map<mp::Session,Limit::Ses *> m_sessions;
-
int m_bw_max;
int m_pdu_max;
int m_search_max;
}
}
- yaz_log(YLOG_LOG, "sz = %d . total = %d", sz,
- ses->bw_stat.get_total());
-
int bw_total = ses->bw_stat.get_total();
int pdu_total = ses->pdu_stat.get_total();
int search_total = ses->search_stat.get_total();
};
}
-// bandwidth class (taken from YAZ Proxy)
-
-Yaz_bw::Yaz_bw(int sz)
-{
- m_sec = 0;
- m_size = sz;
- m_bucket = new int[m_size];
- m_ptr = 0;
-}
-
-Yaz_bw::~Yaz_bw()
-{
- delete [] m_bucket;
-}
-
-int Yaz_bw::get_total()
-{
- add_bytes(0);
- int bw = 0;
- int i;
- for (i = 0; i<m_size; i++)
- bw += m_bucket[i];
- return bw;
-}
-
-void Yaz_bw::add_bytes(int b)
-{
- long now = time(0);
-
- if (now >= m_sec)
- {
- int d = now - m_sec;
- if (d > m_size)
- d = m_size;
- while (--d >= 0)
- {
- if (++m_ptr == m_size)
- m_ptr = 0;
- m_bucket[m_ptr] = 0;
- }
- m_bucket[m_ptr] += b;
- }
- m_sec = now;
-}
/*
* Local variables:
extern struct metaproxy_1_filter_struct metaproxy_1_filter_limit;
}
-class Yaz_bw {
- public:
- Yaz_bw(int sz);
- ~Yaz_bw();
- void add_bytes(int m);
- int get_total();
- private:
- long m_sec; // time of most recent bucket
- int *m_bucket;
- int m_ptr;
- int m_size;
-};
#endif
/*
m_origin_id = s;
}
+std::string mp::Origin::get_address()
+{
+ return m_address;
+}
+
std::ostream& std::operator<<(std::ostream& os, mp::Origin& o)
{
if (o.m_address != "")
/// set max sockets (for outgoing connections to a given target)
int get_max_sockets();
+
+ /// get tcpip address
+ std::string get_address();
private:
friend std::ostream&
std::operator<<(std::ostream& os, metaproxy_1::Origin& o);
attribute name { xsd:NCName }?,
element mp:threads { xsd:integer }?,
element mp:port { xsd:string }+,
- element mp:timeout { xsd:integer }?
+ element mp:timeout { xsd:integer }?,
+ element mp:connect-max { xsd:integer }?
filter_http_file =
attribute type { "http_file" },
<data type="integer"/>
</element>
</optional>
+ <optional>
+ <element name="mp:connect-max">
+ <data type="integer"/>
+ </element>
+ </optional>
</define>
<define name="filter_http_file">
<attribute name="type">
<xs:element minOccurs="0" ref="mp:threads"/>
<xs:element maxOccurs="unbounded" ref="mp:port"/>
<xs:element minOccurs="0" ref="mp:timeout"/>
+ <xs:element minOccurs="0" ref="mp:connect-max"/>
</xs:sequence>
</xs:group>
<xs:element name="threads" type="xs:integer"/>
<xs:element name="port" type="xs:string"/>
<xs:element name="timeout" type="xs:integer"/>
+ <xs:element name="connect-max" type="xs:integer"/>
<xs:attributeGroup name="filter_frontend_net">
<xs:attribute name="type" use="required">
<xs:simpleType>