target.cc (1286B)
1 #include "hashedip" 2 3 unsigned HashedIp::target(struct in_addr clientip, 4 BackendVector &targetlist) { 5 6 // Nothing to do if we don't have targets. 7 if (!targetlist.size()) 8 throw Error("Hashed-ip algorithm: no back ends to dispatch to"); 9 10 // Hash the client's IP into an index 11 unsigned h = 0; 12 for (char *cp = (char*)&clientip; 13 unsigned(cp - (char*)&clientip) < sizeof(struct in_addr); 14 cp++) { 15 h += *cp; 16 h %= targetlist.size(); 17 } 18 unsigned index = targetlist[h]; 19 20 msg("Client IP "<< inet2string(clientip) << " hashes to " << index << 21 ", back end " << balancer.backend(index).description() << '\n'); 22 23 // In strict mode, back end must be available, or don't proceed 24 // In lax mode, fall back to least-connections dispatching 25 if (! balancer.backend(index).available()) { 26 if (config.dispatchmode() == Dispatchmode::m_strict_hashed_ip) 27 throw Error("Hashed-IP algorithm: target back end " + 28 balancer.backend(index).description() + 29 " unavailable"); 30 else { 31 msg("Hashed-IP algorithm: target back end " << 32 balancer.backend(index).description() << " unavailable, " 33 << "falling back to least-connections\n"); 34 Leastconn l; 35 index = l.target(clientip, targetlist); 36 } 37 } 38 39 // Got it 40 return (index); 41 }