+ // passing anything but z3950 packages
+ if (gdu_req && gdu_req->which == Z_GDU_Z3950)
+ {
+ // target selecting only on Z39.50 init request
+ if (gdu_req->u.z3950->which == Z_APDU_initRequest)
+ {
+ yazpp_1::GDU base_req(gdu_req);
+ Z_APDU *apdu = base_req.get()->u.z3950;
+
+ Z_InitRequest *org_init = base_req.get()->u.z3950->u.initRequest;
+ mp::odr odr_en(ODR_ENCODE);
+
+ std::list<std::string> vhosts;
+ mp::util::remove_vhost_otherinfo(&(org_init->otherInfo), vhosts);
+ // get lowest of all vhosts.. Remove them if individually if
+ // they turn out to be bad..
+ while (1)
+ {
+ std::string target;
+ std::list<std::string>::iterator ivh = vhosts.begin();
+
+ Package init_pkg(package.session(), package.origin());
+ init_pkg.copy_filter(package);
+
+ unsigned int cost = std::numeric_limits<unsigned int>::max();
+ {
+ boost::mutex::scoped_lock scoped_lock(m_mutex);
+
+ for (; ivh != vhosts.end(); )
+ {
+ if ((*ivh).size() != 0)
+ {
+ unsigned int vhcost
+ = yf::LoadBalance::Impl::cost(*ivh);
+ yaz_log(YLOG_LOG, "Consider %s cost=%u vhcost=%u",
+ (*ivh).c_str(), cost, vhcost);
+ if (cost > vhcost)
+ {
+ cost = vhcost;
+ target = *ivh;
+ ivh = vhosts.erase(ivh);
+ }
+ else
+ ivh++;
+ }
+ else
+ ivh++;
+ }
+ }
+ if (target.length() == 0)
+ break;
+ // copying new target into init package
+
+ yazpp_1::GDU init_gdu(base_req);
+ Z_InitRequest *init_req = init_gdu.get()->u.z3950->u.initRequest;
+
+ mp::util::set_vhost_otherinfo(&(init_req->otherInfo),
+ odr_en, target, 1);
+
+ init_pkg.request() = init_gdu;
+
+ // moving all package types
+ init_pkg.move();
+
+ // checking for closed back end packages
+ if (!init_pkg.session().is_closed())
+ {
+ add_session(package.session().id(), target);
+
+ package.response() = init_pkg.response();
+ return;
+ }
+ }
+ mp::odr odr;
+ package.response() = odr.create_initResponse(
+ apdu, YAZ_BIB1_TEMPORARY_SYSTEM_ERROR,
+ "load_balance: no available targets");
+ package.session().close();
+ return;
+ }
+ // frontend Z39.50 close request is added to statistics and marked
+ else if (gdu_req->u.z3950->which == Z_APDU_close)
+ {
+ is_closed_front = true;
+ boost::mutex::scoped_lock scoped_lock(m_mutex);
+ add_package(package.session().id());
+ }
+ // any other Z39.50 package is added to statistics
+ else
+ {
+ boost::mutex::scoped_lock scoped_lock(m_mutex);
+ add_package(package.session().id());
+ }
+ }
+
+ // moving all package types
+ package.move();
+
+ bool is_closed_back = false;
+
+ // checking for closed back end packages
+ if (package.session().is_closed())
+ is_closed_back = true;
+
+ Z_GDU *gdu_res = package.response().get();