+ Yaz_ProxyClient *cc = 0;
+
+ for (c = parent->m_clientPool; c; c = c->m_next)
+ {
+ assert (c->m_prev);
+ assert (*c->m_prev == c);
+ if (c->m_server == 0 && c->m_cookie == 0 &&
+ !strcmp(m_proxyTarget, c->get_hostname()))
+ {
+ cc = c;
+ }
+ }
+ if (cc)
+ {
+ // found it in cache
+ c = cc;
+
+ yaz_log (LOG_LOG, "Reuse session %d to %d %s",
+ 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)++;
+ return c;
+ }
+ }
+ if (!m_client)
+ {
+ if (apdu->which != Z_APDU_initRequest)
+ {
+ yaz_log (LOG_LOG, "no first INIT!");
+ return 0;
+ }
+ Z_InitRequest *initRequest = apdu->u.initRequest;
+
+ if (!initRequest->idAuthentication)
+ {
+ if (m_proxy_authentication)
+ {
+ initRequest->idAuthentication =
+ (Z_IdAuthentication *)
+ odr_malloc (odr_encode(),
+ sizeof(*initRequest->idAuthentication));
+ initRequest->idAuthentication->which =
+ Z_IdAuthentication_open;
+ initRequest->idAuthentication->u.open =
+ odr_strdup (odr_encode(), m_proxy_authentication);
+ }
+ }
+
+ // go through list of clients - and find the lowest/oldest one.
+ Yaz_ProxyClient *c_min = 0;
+ int min_seq = -1;
+ int no_of_clients = 0;
+ if (parent->m_clientPool)
+ yaz_log (LOG_LOG, "Existing sessions");
+ for (c = parent->m_clientPool; c; c = c->m_next)
+ {
+ yaz_log (LOG_LOG, " Session %-3d wait=%d %s cookie=%s", c->m_seqno,
+ c->m_waiting, c->get_hostname(),
+ c->m_cookie ? c->m_cookie : "");
+ no_of_clients++;
+ if (min_seq < 0 || c->m_seqno < min_seq)
+ {
+ min_seq = c->m_seqno;
+ c_min = c;
+ }
+ }
+ if (no_of_clients >= parent->m_max_clients)
+ {
+ c = c_min;
+ if (c->m_waiting || strcmp(m_proxyTarget, c->get_hostname()))
+ {
+ yaz_log (LOG_LOG, "Replace session %d",
+ c->m_seqno);
+ if (c->m_server && c->m_server != this)
+ delete c->m_server;
+ c->m_server = 0;
+ }
+ else
+ {
+ yaz_log (LOG_LOG, "Move session %d to %d %s",
+ c->m_seqno, parent->m_seqno, c->get_hostname());
+ xfree (c->m_cookie);
+ c->m_cookie = 0;
+ if (cookie)
+ c->m_cookie = xstrdup(cookie);
+ c->m_seqno = parent->m_seqno;
+ if (c->m_server && c->m_server != this)
+ {
+ c->m_server->m_client = 0;
+ delete c->m_server;
+ }
+ (parent->m_seqno)++;
+ yaz_log (LOG_DEBUG, "get_client 2 %p %p", this, c);
+ return c;
+ }
+ }
+ else
+ {
+ yaz_log (LOG_LOG, "Making session %d %s", parent->m_seqno,
+ m_proxyTarget);
+ c = new Yaz_ProxyClient(m_PDU_Observable->clone());
+ c->m_next = parent->m_clientPool;
+ if (c->m_next)
+ c->m_next->m_prev = &c->m_next;
+ parent->m_clientPool = c;
+ c->m_prev = &parent->m_clientPool;
+ }
+
+ xfree (c->m_cookie);
+ c->m_cookie = 0;
+ if (cookie)
+ c->m_cookie = xstrdup(cookie);
+
+ yaz_log (LOG_LOG, "Connecting to %s", m_proxyTarget);
+ c->m_seqno = parent->m_seqno;
+ c->client(m_proxyTarget);
+ c->m_init_flag = 0;
+ c->m_last_resultCount = 0;
+ c->m_last_ok = 0;
+ c->m_cache.clear();
+ c->m_sr_transform = 0;
+ c->m_waiting = 0;
+ c->m_resultSetStartPoint = 0;
+ c->timeout(20);