Implement -p pidfile option
[yazpp-moved-to-github.git] / src / yaz-proxy.cpp
index c726985..c5bd0a7 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 1998-2003, Index Data.
  * See the file LICENSE for details.
  * 
- * $Id: yaz-proxy.cpp,v 1.59 2003-10-14 20:19:43 adam Exp $
+ * $Id: yaz-proxy.cpp,v 1.65 2003-10-23 09:08:52 adam Exp $
  */
 
 #include <assert.h>
@@ -53,7 +53,7 @@ static const char *apdu_name(Z_APDU *apdu)
 }
 
 Yaz_Proxy::Yaz_Proxy(IYaz_PDU_Observable *the_PDU_Observable,
-                    Yaz_Proxy *parent = 0) :
+                    Yaz_Proxy *parent) :
     Yaz_Z_Assoc(the_PDU_Observable), m_bw_stat(60), m_pdu_stat(60)
 {
     m_PDU_Observable = the_PDU_Observable;
@@ -67,11 +67,12 @@ Yaz_Proxy::Yaz_Proxy(IYaz_PDU_Observable *the_PDU_Observable,
     m_default_target = 0;
     m_proxy_authentication = 0;
     m_max_clients = 150;
+    m_log_mask = 0;
     m_seed = time(0);
     m_client_idletime = 600;
     m_target_idletime = 600;
     m_optimize = xstrdup ("1");
-    strcpy(m_session_str, "x");
+    strcpy(m_session_str, "0");
     m_session_no=0;
     m_bytes_sent = m_bytes_recv = 0;
     m_bw_hold_PDU = 0;
@@ -104,6 +105,8 @@ int Yaz_Proxy::set_config(const char *config)
     xfree(m_config_fname);
     m_config_fname = xstrdup(config);
     int r = m_config->read_xml(config);
+    if (!r)
+       m_config->get_generic_info(&m_log_mask, &m_max_clients);
     return r;
 }
 
@@ -139,6 +142,11 @@ Yaz_ProxyConfig *Yaz_Proxy::check_reconfigure()
            int r = cfg->read_xml(m_config_fname);
            if (r)
                yaz_log(LOG_WARN, "reconfigure failed");
+           else
+           {
+               m_log_mask = 0;
+               cfg->get_generic_info(&m_log_mask, &m_max_clients);
+           }
        }
        else
            yaz_log(LOG_LOG, "reconfigure");
@@ -157,7 +165,13 @@ IYaz_PDU_Observer *Yaz_Proxy::sessionNotify(IYaz_PDU_Observable
     new_proxy->timeout(m_client_idletime);
     new_proxy->m_target_idletime = m_target_idletime;
     new_proxy->set_default_target(m_default_target);
+    new_proxy->m_max_clients = m_max_clients;
+    new_proxy->m_log_mask = m_log_mask;
     new_proxy->set_APDU_log(get_APDU_log());
+    if (m_log_mask & PROXY_LOG_APDU_CLIENT)
+       new_proxy->set_APDU_yazlog(1);
+    else
+       new_proxy->set_APDU_yazlog(0);
     new_proxy->set_proxy_authentication(m_proxy_authentication);
     sprintf(new_proxy->m_session_str, "%ld:%d ", (long) time(0), m_session_no);
     m_session_no++;
@@ -244,15 +258,21 @@ Yaz_ProxyClient *Yaz_Proxy::get_client(Z_APDU *apdu)
        Yaz_ProxyConfig *cfg = check_reconfigure();
        if (proxy_host)
        {
+#if 0
+/* only to be enabled for debugging... */
+           if (!strcmp(proxy_host, "stop"))
+               exit(0);
+#endif
            xfree(m_default_target);
            m_default_target = xstrdup(proxy_host);
            proxy_host = m_default_target;
        }
        int client_idletime = -1;
-       int pre_init = 0;
        url[0] = m_default_target;
        url[1] = 0;
        if (cfg)
+       {
+           int pre_init = 0;
            cfg->get_target_info(proxy_host, url, &m_bw_max,
                                 &m_pdu_max, &m_max_record_retrieve,
                                 &m_target_idletime, &client_idletime,
@@ -260,6 +280,7 @@ Yaz_ProxyClient *Yaz_Proxy::get_client(Z_APDU *apdu)
                                 &m_keepalive_limit_bw,
                                 &m_keepalive_limit_pdu,
                                 &pre_init);
+       }
        if (client_idletime != -1)
        {
            m_client_idletime = client_idletime;
@@ -279,9 +300,7 @@ Yaz_ProxyClient *Yaz_Proxy::get_client(Z_APDU *apdu)
            m_proxyTarget = (char*) xstrdup(load_balance(url));
     }
     if (cookie && *cookie)
-    {
-       Yaz_ProxyClient *cc = 0;
-       
+    {   // search in sessions with a cookie
        for (c = parent->m_clientPool; c; c = c->m_next)
        {
            assert (c->m_prev);
@@ -289,50 +308,44 @@ Yaz_ProxyClient *Yaz_Proxy::get_client(Z_APDU *apdu)
            if (c->m_cookie && !strcmp(cookie,c->m_cookie) &&
                !strcmp(m_proxyTarget, c->get_hostname()))
            {
-               cc = c;
-           }
-       }
-       if (cc)
-       {
-           // found it in cache
-           c = cc;
-           // The following handles "cancel"
-           // If connection is busy (waiting for PDU) and
-           // we have an initRequest we can safely do re-open
-           if (c->m_waiting && apdu->which == Z_APDU_initRequest)
-           {
-               yaz_log (LOG_LOG, "%s REOPEN target=%s", m_session_str,
-                        c->get_hostname());
-               c->close();
-               c->m_init_flag = 0;
-
-               c->m_last_ok = 0;
-               c->m_cache.clear();
-               c->m_last_resultCount = 0;
-               c->m_sr_transform = 0;
-               c->m_waiting = 0;
-               c->m_resultSetStartPoint = 0;
-               c->m_target_idletime = m_target_idletime;
-               if (c->client(m_proxyTarget))
+               // Found it in cache
+               // The following handles "cancel"
+               // If connection is busy (waiting for PDU) and
+               // we have an initRequest we can safely do re-open
+               if (c->m_waiting && apdu->which == Z_APDU_initRequest)
                {
-                   delete c;
-                   return 0;
+                   yaz_log (LOG_LOG, "%s REOPEN target=%s", m_session_str,
+                            c->get_hostname());
+                   c->close();
+                   c->m_init_flag = 0;
+                   
+                   c->m_last_ok = 0;
+                   c->m_cache.clear();
+                   c->m_last_resultCount = 0;
+                   c->m_sr_transform = 0;
+                   c->m_waiting = 0;
+                   c->m_resultSetStartPoint = 0;
+                   c->m_target_idletime = m_target_idletime;
+                   if (c->client(m_proxyTarget))
+                   {
+                       delete c;
+                       return 0;
+                   }
+                   c->timeout(30); 
                }
-               c->timeout(30); 
+               c->m_seqno = parent->m_seqno;
+               if (c->m_server && c->m_server != this)
+                   c->m_server->m_client = 0;
+               c->m_server = this;
+               (parent->m_seqno)++;
+               yaz_log (LOG_DEBUG, "get_client 1 %p %p", this, c);
+               return c;
            }
-           c->m_seqno = parent->m_seqno;
-           if (c->m_server && c->m_server != this)
-               c->m_server->m_client = 0;
-           c->m_server = this;
-           (parent->m_seqno)++;
-           yaz_log (LOG_DEBUG, "get_client 1 %p %p", this, c);
-           return c;
        }
     }
     else if (!c)
     {
-       Yaz_ProxyClient *cc = 0;
-       
+       // don't have a client session yet. Search in session w/o cookie
        for (c = parent->m_clientPool; c; c = c->m_next)
        {
            assert (c->m_prev);
@@ -341,27 +354,25 @@ Yaz_ProxyClient *Yaz_Proxy::get_client(Z_APDU *apdu)
                c->m_waiting == 0 &&
                !strcmp(m_proxyTarget, c->get_hostname()))
            {
-               cc = c;
-           }
-       }
-       if (cc)
-       {
-           // found it in cache
-           c = cc;
-
-           yaz_log (LOG_LOG, "%sREUSE %d %d %s",
-                    m_session_str,
-                    c->m_seqno, parent->m_seqno, c->get_hostname());
-
-           c->m_seqno = parent->m_seqno;
-           assert(c->m_server == 0);
-           c->m_server = this;
-           
-           (parent->m_seqno)++;
+               // found it in cache
+               yaz_log (LOG_LOG, "%sREUSE %s",
+                        m_session_str, c->get_hostname());
+               
+               c->m_seqno = parent->m_seqno;
+               assert(c->m_server == 0);
+               c->m_server = this;
 
-           parent->pre_init();
+               if (parent->m_log_mask & PROXY_LOG_APDU_SERVER)
+                   c->set_APDU_yazlog(1);
+               else
+                   c->set_APDU_yazlog(0);
 
-           return c;
+               (parent->m_seqno)++;
+               
+               parent->pre_init();
+               
+               return c;
+           }
        }
     }
     if (!m_client)
@@ -435,6 +446,12 @@ Yaz_ProxyClient *Yaz_Proxy::get_client(Z_APDU *apdu)
                (parent->m_seqno)++;
                c->m_target_idletime = m_target_idletime;
                c->timeout(m_target_idletime);
+               
+               if (parent->m_log_mask & PROXY_LOG_APDU_SERVER)
+                   c->set_APDU_yazlog(1);
+               else
+                   c->set_APDU_yazlog(0);
+
                return c;
            }
        }
@@ -472,6 +489,10 @@ Yaz_ProxyClient *Yaz_Proxy::get_client(Z_APDU *apdu)
        c->m_target_idletime = m_target_idletime;
        c->timeout(30);
 
+       if (parent->m_log_mask & PROXY_LOG_APDU_SERVER)
+           c->set_APDU_yazlog(1);
+       else
+           c->set_APDU_yazlog(0);
     }
     yaz_log (LOG_DEBUG, "get_client 3 %p %p", this, c);
     return c;
@@ -618,8 +639,9 @@ int Yaz_Proxy::send_to_client(Z_APDU *apdu)
            convert_to_marcxml(p->u.databaseOrSurDiagnostics);
     }
     int r = send_Z_PDU(apdu, &len);
-    yaz_log (LOG_DEBUG, "%sSending %s to client %d bytes", m_session_str,
-            apdu_name(apdu), len);
+    if (m_log_mask & PROXY_LOG_APDU_CLIENT)
+       yaz_log (LOG_DEBUG, "%sSending %s to client %d bytes", m_session_str,
+                apdu_name(apdu), len);
     m_bytes_sent += len;
     m_bw_stat.add_bytes(len);
     return r;
@@ -629,9 +651,10 @@ int Yaz_ProxyClient::send_to_target(Z_APDU *apdu)
 {
     int len = 0;
     int r = send_Z_PDU(apdu, &len);
-    yaz_log (LOG_LOG, "%sSending %s to %s %d bytes",
-            get_session_str(),
-            apdu_name(apdu), get_hostname(), len);
+    if (m_root->get_log_mask() & PROXY_LOG_REQ_SERVER)
+       yaz_log (LOG_LOG, "%sSending %s to %s %d bytes",
+                get_session_str(),
+                apdu_name(apdu), get_hostname(), len);
     m_bytes_sent += len;
     return r;
 }
@@ -641,7 +664,6 @@ Z_APDU *Yaz_Proxy::result_set_optimize(Z_APDU *apdu)
     if (apdu->which == Z_APDU_presentRequest)
     {
        Z_PresentRequest *pr = apdu->u.presentRequest;
-       Z_NamePlusRecordList *npr;
        int toget = *pr->numberOfRecordsRequested;
        int start = *pr->resultSetStartPoint;
 
@@ -660,6 +682,7 @@ Z_APDU *Yaz_Proxy::result_set_optimize(Z_APDU *apdu)
            send_to_client(new_apdu);
            return 0;
        }
+#if 0
        if (!strcmp(m_client->m_last_resultSetId, pr->resultSetId))
        {
            if (start+toget-1 > m_client->m_last_resultCount)
@@ -693,6 +716,7 @@ Z_APDU *Yaz_Proxy::result_set_optimize(Z_APDU *apdu)
                return 0;
            }
        }
+#endif
     }
 
     if (apdu->which != Z_APDU_searchRequest)
@@ -874,8 +898,9 @@ void Yaz_Proxy::recv_Z_PDU(Z_APDU *apdu, int len)
     int reduce = 0;
     m_bytes_recv += len;
     
-    yaz_log (LOG_DEBUG, "%sReceiving %s from client %d bytes", m_session_str,
-            apdu_name(apdu), len);
+    if (m_log_mask & PROXY_LOG_APDU_CLIENT)
+       yaz_log (LOG_DEBUG, "%sReceiving %s from client %d bytes",
+                m_session_str, apdu_name(apdu), len);
 
     if (m_bw_hold_PDU)     // double incoming PDU. shutdown now.
        shutdown();
@@ -985,37 +1010,34 @@ Z_APDU *Yaz_Proxy::handle_syntax_validation(Z_APDU *apdu)
     if (apdu->which == Z_APDU_searchRequest)
     {
        Z_SearchRequest *sr = apdu->u.searchRequest;
-       if (*sr->smallSetUpperBound > 0 || *sr->mediumSetPresentNumber > 0)
+       int err = 0;
+       char *addinfo = 0;
+       Yaz_ProxyConfig *cfg = check_reconfigure();
+       
+       if (cfg)
+           err = cfg->check_syntax(odr_encode(),
+                                   m_default_target,
+                                   sr->preferredRecordSyntax,
+                                   &addinfo);
+       if (err == -1)
        {
-           int err = 0;
-           char *addinfo = 0;
-           Yaz_ProxyConfig *cfg = check_reconfigure();
-
-           if (cfg)
-               err = cfg->check_syntax(odr_encode(),
-                                       m_default_target,
-                                       sr->preferredRecordSyntax,
-                                       &addinfo);
-           if (err == -1)
-           {
-               sr->preferredRecordSyntax =
-                   yaz_oidval_to_z3950oid(odr_decode(), CLASS_RECSYN,
-                                          VAL_USMARC);
-               m_marcxml_flag = 1;
-           }
-           else if (err)
-           {
-               Z_APDU *new_apdu = create_Z_PDU(Z_APDU_searchResponse);
-               
-               new_apdu->u.searchResponse->referenceId = sr->referenceId;
-               new_apdu->u.searchResponse->records =
-                   create_nonSurrogateDiagnostics(odr_encode(), err, addinfo);
-               *new_apdu->u.searchResponse->searchStatus = 0;
-               
-               send_to_client(new_apdu);
-               
-               return 0;
-           }
+           sr->preferredRecordSyntax =
+               yaz_oidval_to_z3950oid(odr_decode(), CLASS_RECSYN,
+                                      VAL_USMARC);
+           m_marcxml_flag = 1;
+       }
+       else if (err)
+       {
+           Z_APDU *new_apdu = create_Z_PDU(Z_APDU_searchResponse);
+           
+           new_apdu->u.searchResponse->referenceId = sr->referenceId;
+           new_apdu->u.searchResponse->records =
+               create_nonSurrogateDiagnostics(odr_encode(), err, addinfo);
+           *new_apdu->u.searchResponse->searchStatus = 0;
+           
+           send_to_client(new_apdu);
+           
+           return 0;
        }
     }
     else if (apdu->which == Z_APDU_presentRequest)
@@ -1213,7 +1235,6 @@ void Yaz_ProxyClient::connectNotify()
     const char *h = get_hostname();
     yaz_log (LOG_LOG, "%sConnection accepted by %s timeout=%d", s, h,
             m_target_idletime);
-    int to;
     timeout(m_target_idletime);
     if (!m_server)
        pre_init_client();
@@ -1280,8 +1301,13 @@ void Yaz_Proxy::pre_init()
 
     Yaz_ProxyConfig *cfg = check_reconfigure();
 
-    yaz_log(LOG_LOG, "pre_init");
     zurl_in_use[0] = 0;
+
+    if (m_log_mask & PROXY_LOG_APDU_CLIENT)
+       set_APDU_yazlog(1);
+    else
+       set_APDU_yazlog(0);
+
     for (i = 0; cfg && cfg->get_target_no(i, &name, zurl_in_use,
                                          &limit_bw, &limit_pdu, &limit_req,
                                          &target_idletime, &client_idletime,
@@ -1297,14 +1323,26 @@ void Yaz_Proxy::pre_init()
            {
                Yaz_ProxyClient *c;
                int spare = 0;
+               int in_use = 0;
+               int other = 0;
                for (c = m_clientPool; c; c = c->m_next)
                {
-                   if (!strcmp(zurl_in_use[j], c->get_hostname())
-                       && c->m_server == 0 && c->m_cookie == 0)
-                       spare++;
+                   if (!strcmp(zurl_in_use[j], c->get_hostname()))
+                   {
+                       if (c->m_cookie == 0)
+                       {
+                           if (c->m_server == 0)
+                               spare++;
+                           else
+                               in_use++;
+                       }
+                       else
+                           other++;
+                   }
                }
-               yaz_log(LOG_LOG, "pre_init %s %s spare=%d pre_init=%d",
-                       name, zurl_in_use[j], spare, pre_init);
+               yaz_log(LOG_LOG, "%s pre-init %s %s use=%d other=%d spare=%d preinit=%d",
+                       m_session_str,
+                       name, zurl_in_use[j], in_use, other, spare, pre_init);
                if (spare < pre_init)
                {
                    c = new Yaz_ProxyClient(m_PDU_Observable->clone(), this);
@@ -1314,6 +1352,11 @@ void Yaz_Proxy::pre_init()
                    m_clientPool = c;
                    c->m_prev = &m_clientPool;
                    
+                   if (m_log_mask & PROXY_LOG_APDU_SERVER)
+                       c->set_APDU_yazlog(1);
+                   else
+                       c->set_APDU_yazlog(0);
+
                    if (c->client(zurl_in_use[j]))
                    {
                        timeout(60);
@@ -1323,8 +1366,6 @@ void Yaz_Proxy::pre_init()
                    c->timeout(30);
                    c->m_waiting = 1;
                    c->m_target_idletime = target_idletime;
-                   yaz_log(LOG_LOG, "pre_init name=%s zurl=%s timeout=%d", name,
-                           zurl_in_use[j], target_idletime);
                    c->m_seqno = m_seqno++;
                }
            }
@@ -1407,8 +1448,9 @@ void Yaz_ProxyClient::recv_Z_PDU(Z_APDU *apdu, int len)
     m_bytes_recv += len;
     m_pdu_recv++;
     m_waiting = 0;
-    yaz_log (LOG_LOG, "%sReceiving %s from %s %d bytes", get_session_str(),
-            apdu_name(apdu), get_hostname(), len);
+    if (m_root->get_log_mask() & PROXY_LOG_REQ_SERVER)
+       yaz_log (LOG_LOG, "%sReceiving %s from %s %d bytes", get_session_str(),
+                apdu_name(apdu), get_hostname(), len);
     if (apdu->which == Z_APDU_initResponse)
     {
        if (!m_server)  // if this is a pre init session , check for more
@@ -1491,6 +1533,7 @@ void Yaz_Proxy::server(const char *addr)
 {
     Yaz_Z_Assoc::server(addr);
 
+    yaz_log(LOG_LOG, "started OK");
     timeout(1);
 }