From: Adam Dickmeiss Date: Wed, 19 Mar 2008 17:03:27 +0000 (+0100) Subject: Allow max-sockets in use to a particular target to be configured. X-Git-Tag: v1.3.3~5 X-Git-Url: http://git.indexdata.com/?p=yazproxy-moved-to-github.git;a=commitdiff_plain;h=d119ba229b6c9257c4efb634bf7425d6595196ff Allow max-sockets in use to a particular target to be configured. The per-target setting 'max-sockets' allows number of sockets to be in use. If reached and HTTP is in use a HTTP response with status code 500 is returned. --- diff --git a/doc/reference.xml b/doc/reference.xml index 5fa7146..158f97d 100644 --- a/doc/reference.xml +++ b/doc/reference.xml @@ -213,7 +213,7 @@ The proxy config file must have a root element called proxy and scoped within namespace - xmlns="http://indexdata.dk/yazproxy/schema/0.9/. + xmlns="http://indexdata.dk/yazproxy/schema/0.9/". All information except an optional XML header must be stored within the proxy element. @@ -237,16 +237,17 @@ equivalent to command line option -t. - - <?xml version="1.0"?> - <proxy xmlns="http://indexdata.dk/yazproxy/schema/0.9/"> - <target name="server1" default="1"> - <!-- description of server1 .. --> - </target> - <target name="server2"> - <!-- description of server2 .. --> - </target> - </proxy> + + + + + + + + + + ]]> @@ -291,6 +292,16 @@ +
+ client-timeout + + The element max-sockets is the child of element + target and specifies the maximum number of sockets + to use for the target for all sessions using it. In other words: maximum + number of Z39.50 session to the target. + +
+
keepalive The keepalive element holds information about @@ -859,6 +870,7 @@ + @@ -880,6 +892,7 @@ + diff --git a/etc/config.xml b/etc/config.xml index ca243e0..3c84edb 100644 --- a/etc/config.xml +++ b/etc/config.xml @@ -10,6 +10,7 @@ localhost:9999 60 20 + 8 100000 @@ -42,7 +43,7 @@ - 2 + 0 iso-8859-1 pqf.properties diff --git a/include/yazproxy/proxy.h b/include/yazproxy/proxy.h index 25ef079..0357948 100644 --- a/include/yazproxy/proxy.h +++ b/include/yazproxy/proxy.h @@ -69,8 +69,9 @@ class YAZ_EXPORT Yaz_Proxy : public yazpp_1::Z_Assoc { void HTTP_Forwarded(Z_GDU *z_gdu); void connect_stat(bool &block, int &reduce); Yaz_ProxyClient *get_client(Z_APDU *apdu, const char *cookie, - const char *proxy_host); + const char *proxy_host, int *http_code); void srw_get_client(const char *db, const char **backend_db); + int get_number_of_connections(); Z_APDU *result_set_optimize(Z_APDU *apdu); void releaseClient(); Yaz_ProxyClient *m_client; @@ -85,6 +86,7 @@ class YAZ_EXPORT Yaz_Proxy : public yazpp_1::Z_Assoc { int m_keepalive_limit_pdu; int m_client_idletime; int m_target_idletime; + int m_max_sockets; int m_debug_mode; char *m_proxyTarget; char *m_default_target; diff --git a/src/proxyp.h b/src/proxyp.h index f87ec92..cc19d99 100644 --- a/src/proxyp.h +++ b/src/proxyp.h @@ -115,6 +115,7 @@ public: int *limit_bw, int *limit_pdu, int *limit_req, int *limit_search, int *target_idletime, int *client_idletime, + int *max_sockets, int *max_clients, int *keepalive_limit_bw, int *keepalive_limit_pdu, int *pre_init, diff --git a/src/yaz-proxy-config.cpp b/src/yaz-proxy-config.cpp index b59d88a..edd5d85 100644 --- a/src/yaz-proxy-config.cpp +++ b/src/yaz-proxy-config.cpp @@ -42,6 +42,7 @@ class Yaz_ProxyConfigP { int *limit_bw, int *limit_pdu, int *limit_req, int *limit_search, int *target_idletime, int *client_idletime, + int *max_sockets, int *keepalive_limit_bw, int *keepalive_limit_pdu, int *pre_init, const char **cql2rpn, const char **negotiation_charset, @@ -231,6 +232,7 @@ void Yaz_ProxyConfigP::return_target_info(xmlNodePtr ptr, int *limit_search, int *target_idletime, int *client_idletime, + int *max_sockets, int *keepalive_limit_bw, int *keepalive_limit_pdu, int *pre_init, @@ -297,6 +299,15 @@ void Yaz_ProxyConfigP::return_target_info(xmlNodePtr ptr, } } if (ptr->type == XML_ELEMENT_NODE + && !strcmp((const char *) ptr->name, "max-sockets")) + { + const char *t = get_text(ptr); + if (t && max_sockets) + { + *max_sockets = atoi(t); + } + } + if (ptr->type == XML_ELEMENT_NODE && !strcmp((const char *) ptr->name, "cql2rpn")) { const char *t = get_text(ptr); @@ -1018,6 +1029,7 @@ int Yaz_ProxyConfig::get_target_no(int no, limit_bw, limit_pdu, limit_req, limit_search, target_idletime, client_idletime, + 0, keepalive_limit_bw, keepalive_limit_pdu, pre_init, cql2rpn, negotiation_charset, negotiation_lang, target_charset, @@ -1297,6 +1309,7 @@ void Yaz_ProxyConfig::get_target_info(const char *name, int *limit_search, int *target_idletime, int *client_idletime, + int *max_sockets, int *max_clients, int *keepalive_limit_bw, int *keepalive_limit_pdu, @@ -1341,6 +1354,7 @@ void Yaz_ProxyConfig::get_target_info(const char *name, m_cp->return_target_info(ptr, url, limit_bw, limit_pdu, limit_req, limit_search, target_idletime, client_idletime, + max_sockets, keepalive_limit_bw, keepalive_limit_pdu, pre_init, cql2rpn, negotiation_charset, negotiation_lang, diff --git a/src/yaz-proxy.cpp b/src/yaz-proxy.cpp index 258c5b4..147d066 100644 --- a/src/yaz-proxy.cpp +++ b/src/yaz-proxy.cpp @@ -1,5 +1,5 @@ /* $Id: yaz-proxy.cpp,v 1.78 2008-02-21 09:33:23 adam Exp $ - Copyright (c) 1998-2007, Index Data. + Copyright (c) 1998-2008, Index Data. This file is part of the yazproxy. @@ -220,6 +220,7 @@ Yaz_Proxy::Yaz_Proxy(IPDU_Observable *the_PDU_Observable, m_seed = time(0); m_client_idletime = 600; m_target_idletime = 600; + m_max_sockets = 1024; m_optimize = xstrdup ("1"); strcpy(m_session_str, "0 "); m_session_no = 0; @@ -546,8 +547,27 @@ const char *Yaz_Proxy::load_balance(const char **url) return ret_min; } +int Yaz_Proxy::get_number_of_connections() +{ + int no_connections = 0; + Yaz_ProxyClient *c; + + for (c = m_parent->m_clientPool; c; c = c->m_next) + { + assert(c->m_prev); + assert(*c->m_prev == c); + if (!strcmp(m_proxyTarget, c->get_hostname())) + { + no_connections++; + } + } + yaz_log (YLOG_LOG, "%sExisting %s connections: %d", m_session_str, m_proxyTarget, + no_connections); + return no_connections; +} + Yaz_ProxyClient *Yaz_Proxy::get_client(Z_APDU *apdu, const char *cookie, - const char *proxy_host) + const char *proxy_host, int *http_code) { assert (m_parent); Yaz_Proxy *parent = m_parent; @@ -584,6 +604,7 @@ Yaz_ProxyClient *Yaz_Proxy::get_client(Z_APDU *apdu, const char *cookie, &m_pdu_max, &m_max_record_retrieve, &m_search_max, &m_target_idletime, &client_idletime, + &m_max_sockets, &parent->m_max_clients, &m_keepalive_limit_bw, &m_keepalive_limit_pdu, @@ -679,7 +700,7 @@ Yaz_ProxyClient *Yaz_Proxy::get_client(Z_APDU *apdu, const char *cookie, { assert(c->m_prev); assert(*c->m_prev == c); - if (c->m_server == 0 && c->m_cookie == 0 && c->m_waiting == 0 + if (c->m_server == 0 && c->m_cookie == 0 && c->m_waiting == 0 && c->compare_idAuthentication(apdu) && c->compare_charset(apdu) && !strcmp(m_proxyTarget, c->get_hostname())) @@ -710,6 +731,16 @@ Yaz_ProxyClient *Yaz_Proxy::get_client(Z_APDU *apdu, const char *cookie, if (apdu->which != Z_APDU_initRequest) { yaz_log (YLOG_LOG, "%sno init request as first PDU", m_session_str); + *http_code = 500; + return 0; + } + + int no_in_use = get_number_of_connections(); + if (no_in_use >= m_max_sockets) + { + yaz_log (YLOG_LOG, "%smax sockets reached %d", m_session_str, + m_max_sockets); + *http_code = 500; return 0; } // go through list of clients - and find the lowest/oldest one. @@ -769,6 +800,7 @@ Yaz_ProxyClient *Yaz_Proxy::get_client(Z_APDU *apdu, const char *cookie, } else { + yaz_log (YLOG_LOG, "%sNEW %d %s", m_session_str, parent->m_seqno, m_proxyTarget); c = new Yaz_ProxyClient(m_PDU_Observable->clone(), parent); @@ -2798,8 +2830,6 @@ void Yaz_Proxy::handle_incoming_HTTP(Z_HTTP_Request *hreq) else { // Use _client_ IP as shown in the log entries...! - yaz_log(YLOG_LOG, "No authorization_str present: use client IP: %s\n", m_peername); - auth = (Z_IdAuthentication *) odr_malloc(m_s2z_odr_init, sizeof(Z_IdAuthentication)); auth->which = Z_IdAuthentication_idPass; auth->u.idPass = (Z_IdPass *) odr_malloc(m_s2z_odr_init, sizeof(Z_IdPass)); @@ -3249,12 +3279,13 @@ void Yaz_Proxy::handle_incoming_Z_PDU(Z_APDU *apdu) // Determine our client. Z_OtherInformation **oi; get_otherInfoAPDU(apdu, &oi); - m_client = get_client(apdu, get_cookie(oi), get_proxy(oi)); + int http_code = 404; + m_client = get_client(apdu, get_cookie(oi), get_proxy(oi), &http_code); if (!m_client) { if (m_http_version) { // HTTP. Send not found - send_http_response(404); + send_http_response(http_code); return; } else