static const SSERV_Info* s_GetNextInfo(SServiceConnector* uuu) { if (uuu->params.get_next_info) return uuu->params.get_next_info(uuu->iter, uuu->params.data); else return SERV_GetNextInfo(uuu->iter); }
void CDBLB_ServiceMapper::GetServersList(const string& service, list<string>* serv_list) const { serv_list->clear(); SConnNetInfo* net_info = ConnNetInfo_Create(service.c_str()); SERV_ITER srv_it = SERV_Open(service.c_str(), fSERV_Standalone | fSERV_IncludeDown, 0, net_info); ConnNetInfo_Destroy(net_info); const SSERV_Info* sinfo; while ((sinfo = SERV_GetNextInfo(srv_it)) != NULL) { if (sinfo->time > 0 && sinfo->time != NCBI_TIME_INFINITE) { string server_name(CSocketAPI::ntoa(sinfo->host)); if (sinfo->port != 0) { server_name.append(1, ':'); server_name.append(NStr::UIntToString(sinfo->port)); } serv_list->push_back(server_name); } } SERV_Close(srv_it); }
const char* DBLB_GetServer(const char* lb_name, TDBLB_Flags flags, const SDBLB_Preference* preference, const char* const skip_servers[], SDBLB_ConnPoint* conn_point, char* server_name_buf, size_t server_name_buflen, EDBLB_Status* result) { static const char kPrefix[] = "DB_IP__"; size_t len, n, a_skip, n_skip; SConnNetInfo* net_info; int/*bool*/ failed; unsigned int x_host; unsigned short x_port; double x_pref; SSERV_InfoCPtr* skip; SSERV_Info* info; SDBLB_ConnPoint cp; EDBLB_Status x; const char* c; if (!result) result = &x; if (server_name_buf) { assert(server_name_buflen); server_name_buf[0] = '\0'; } if (!conn_point) conn_point = &cp; memset(conn_point, 0, sizeof(*conn_point)); if (!lb_name || !*lb_name) { *result = eDBLB_BadName; return 0/*failure*/; } *result = eDBLB_Success; if (strchr(lb_name, '.')) { cp.host = SOCK_gethostbyname(lb_name); if (cp.host == SOCK_GetLoopbackAddress()) cp.host = /*FIXME?*/SERV_LOCALHOST; } else cp.host = 0; skip = 0; n_skip = 0; a_skip = 0; net_info = 0; failed = 0/*false*/; if (skip_servers) { for (n = 0; !failed && skip_servers[n]; n++) { const char* server = skip_servers[n]; SSERV_Info* info; if (!(len = strlen(server))) { continue; } if (strncasecmp(server, kPrefix, sizeof(kPrefix)-1) == 0 && isdigit((unsigned char) server[sizeof(kPrefix)-1])) { c = strstr(server + sizeof(kPrefix)-1, "__"); if (c) { size_t i = (size_t)(c - server) - (sizeof(kPrefix)-1); char* temp = strdup(server + sizeof(kPrefix)-1); if (temp) { char* s = temp + i; *s++ = ':'; memmove(s, s + 1, strlen(s + 1) + 1); server = temp; while (++temp < s) { if (*temp == '_') *temp = '.'; } len -= sizeof(kPrefix); } } } if (SOCK_StringToHostPort(server, &x_host, &x_port) != server + len) { int/*bool*/ resolved = 0/*false*/; const SSERV_Info* temp; SERV_ITER iter; if (!net_info) net_info = ConnNetInfo_Create(lb_name); iter = SERV_Open(skip_servers[n], fSERV_Standalone | fSERV_Dns | fSERV_Promiscuous, 0, net_info); do { SSERV_Info* dns; temp = SERV_GetNextInfo(iter); if (temp) { x_host = temp->host; if (x_host && s_IsSkipHost(x_host, cp.host)) { failed = 1/*true*/; break; } x_port = temp->port; } else if (!resolved) { x_host = 0; x_port = 0; } else break; if ((dns = SERV_CreateDnsInfo(x_host)) != 0) { dns->port = x_port; s_AddSkip(&skip, &a_skip, &n_skip, x_host ? dns : SERV_CopyInfoEx(dns, skip_servers[n])); if (!x_host) free(dns); } resolved = 1/*true*/; } while (temp); SERV_Close(iter); info = 0; } else if (s_IsSkipHost(x_host, cp.host)) { failed = 1/*true*/; info = 0; } else if (server != skip_servers[n]) { info = SERV_CreateStandaloneInfo(x_host, x_port); } else if ((info = SERV_CreateDnsInfo(x_host)) != 0) info->port = x_port; if (server != skip_servers[n]) free((void*) server); if (info) s_AddSkip(&skip, &a_skip, &n_skip, info); } } if (!failed && !cp.host) { if (preference) { x_host = preference->host; x_port = preference->port; if ((x_pref = preference->pref) < 0.0) x_pref = 0.0; else if (x_pref >= 100.0) x_pref = -1.0; } else { x_host = 0; x_port = 0; x_pref = 0.0; } if (!net_info) net_info = ConnNetInfo_Create(lb_name); info = SERV_GetInfoP(lb_name, fSERV_ReverseDns | fSERV_Standalone, x_host, x_port, x_pref, net_info, skip, n_skip, 0/*not external*/, 0, 0, 0); /* NCBI_FAKE_WARNING: GCC */ if (!info && (flags & fDBLB_AllowFallbackToStandby)) { /*FIXME: eliminate second pass by fix in ordering in ncbi_lbsmd.c*/ info = SERV_GetInfoP(lb_name, fSERV_ReverseDns | fSERV_Standalone | fSERV_IncludeSuppressed, x_host, x_port, x_pref, net_info, skip, n_skip, 0/*not external*/, 0, 0, 0); /* NCBI_FAKE_WARNING: GCC */ } } else info = 0; if (!info) { if (!failed) { if (!cp.host) { if (n_skip && (x_host = SOCK_gethostbyname(lb_name)) != 0) { for (n = 0; n < n_skip; n++) { if (x_host == skip[n]->host) { failed = 1/*true*/; break; } } } if (!failed && skip_servers) { for (n = 0; (c = skip_servers[n]) != 0; n++) { if (strcasecmp(c, lb_name) == 0) { failed = 1/*true*/; break; } } } } else if (conn_point != &cp) { conn_point->host = cp.host; conn_point->time = NCBI_TIME_INFINITE; } } if (!failed && server_name_buf) strncpy0(server_name_buf, lb_name, server_name_buflen - 1); *result = eDBLB_NotFound; } else { if (info->type != fSERV_Dns) { char* s, buf[80]; strncpy0(buf, kPrefix, sizeof(buf) - 1); SOCK_HostPortToString(info->host, info->port, buf + sizeof(kPrefix) - 1, sizeof(buf) - sizeof(kPrefix)); len = strlen(buf); if ((s = strchr(buf, ':')) != 0) memmove(s + 1, s, strlen(s) + 1); for (n = 0; n < len; n++) { if (buf[n] == '.' || buf[n] == ':') buf[n] = '_'; } if (server_name_buf) strncpy0(server_name_buf, buf, server_name_buflen - 1); *result = eDBLB_NoDNSEntry; } else if (info->host) { c = SERV_NameOfInfo(info); assert(c); if (server_name_buf) strncpy0(server_name_buf, c, server_name_buflen - 1); } else { failed = 1/*true*/; *result = eDBLB_ServiceDown; } if (!failed) { conn_point->host = info->host; conn_point->port = info->port; conn_point->time = info->time; } free(info); } for (n = 0; n < n_skip; n++) free((void*) skip[n]); if (skip) free((void*) skip); if (net_info) ConnNetInfo_Destroy(net_info); return failed ? 0 : (server_name_buf ? server_name_buf : lb_name); }
EIO_Status CConnTest::ServiceOkay(string* reason) { static const char kService[] = "bounce"; SConnNetInfo* net_info = ConnNetInfo_Create(kService, m_DebugPrintout); if (net_info) net_info->lb_disable = 1/*no local LB to use even if available*/; PreCheck(eStatelessService, 0/*main*/, "Checking whether NCBI services operational"); CConn_ServiceStream svc(kService, fSERV_Stateless, net_info, 0/*extra*/, m_Timeout); svc.SetCanceledCallback(m_Canceled); svc << kTest << NcbiEndl; string temp; svc >> temp; bool responded = temp.size() > 0 ? true : false; EIO_Status status = ConnStatus(NStr::Compare(temp, kTest) != 0, &svc); if (status == eIO_Interrupt) temp = kCanceled; else if (status == eIO_Success) temp = "OK"; else { char* str = net_info ? SERV_ServiceName(kService) : 0; if (str && NStr::CompareNocase(str, kService) == 0) { free(str); str = 0; } SERV_ITER iter = SERV_OpenSimple(kService); if (!iter || !SERV_GetNextInfo(iter)) { // Service not found SERV_Close(iter); iter = SERV_OpenSimple(kTest); if (!iter || !SERV_GetNextInfo(iter) || NStr::CompareNocase(SERV_MapperName(iter), "DISPD") != 0) { // Make sure there will be a mapper error printed SERV_Close(iter); temp.clear(); iter = 0; } else { // kTest service can be located but not kService temp = str ? "Substituted service" : "Service"; temp += " cannot be located"; } } else { temp = responded ? "Unrecognized" : "No"; temp += " response from "; temp += str ? "substituted service" : "service"; } if (!temp.empty()) { if (str) { temp += "; please remove ["; string upper(kService); temp += NStr::ToUpper(upper); temp += "]CONN_SERVICE_NAME=\""; temp += str; temp += "\" from your configuration\n"; } else if (status != eIO_Timeout || m_Timeout > kTimeout) temp += "; please contact " + HELP_EMAIL + '\n'; } if (status != eIO_Timeout) { const char* mapper = SERV_MapperName(iter); if (!mapper || NStr::CompareNocase(mapper, "DISPD") != 0) { temp += "Network dispatcher is not enabled as a service" " locator; please review your configuration to purge any" " occurrences of [CONN]DISPD_DISABLE off your settings\n"; } } else temp += x_TimeoutMsg(); SERV_Close(iter); if (str) free(str); } PostCheck(eStatelessService, 0/*main*/, status, temp); ConnNetInfo_Destroy(net_info); if (reason) reason->swap(temp); return status; }
static int run_a_test(size_t test_idx, int live, const char *svc, const char *hdr, int check_for_match, int exp_err, const char *mock_body_in, int repop, int reset) { const SSERV_Info *info = NULL; SConnNetInfo *net_info; SERV_ITER iter; const char *mock_body = NULL; char *mock_body_adj = NULL; int n_matches_perfect = 0, n_matches_near = 0; int success = 0, errors = 0; int retval = -1; s_n_hits_got = 0; /* Adjust mock data for current time, if necessary. */ adjust_mock_times(mock_body_in, &mock_body_adj); mock_body = mock_body_adj ? mock_body_adj : mock_body_in; /* Select the HTTP data source (live or mock). */ s_results[test_idx].live = live; if ( ! s_results[test_idx].live && ( ! mock_body || ! *mock_body)) { CORE_TRACE("Mock HTTP data source unavailable."); s_results[test_idx].live = 1; } if (s_results[test_idx].live) { CORE_TRACE("Using a live HTTP data source."); SERV_NAMERD_SetConnectorSource(NULL); /* use live HTTP */ } else { CORE_TRACE("Using a mock HTTP data source."); if ( ! SERV_NAMERD_SetConnectorSource(mock_body)) { CORE_LOG(eLOG_Error, "Unable to create mock HTTP data source."); retval = 1; goto out; } } /* Set up the server iterator. */ net_info = ConnNetInfo_Create(svc); if (*hdr) ConnNetInfo_SetUserHeader(net_info, hdr); iter = SERV_OpenP(svc, fSERV_All | (strpbrk(svc, "?*") ? fSERV_Promiscuous : 0), SERV_LOCALHOST, 0/*port*/, 0.0/*preference*/, net_info, 0/*skip*/, 0/*n_skip*/, 0/*external*/, 0/*arg*/, 0/*val*/); ConnNetInfo_Destroy(net_info); /* Fetch the server hits from namerd. */ if (iter) { for (; s_n_hits_got < MAX_HITS && (info = SERV_GetNextInfo(iter)); ++s_n_hits_got) { if (info->type & fSERV_Http) { CORE_LOGF(eLOG_Note, (" HTTP extra (path): %s", SERV_HTTP_PATH(&info->u.http))); } strcpy(s_hits_got[s_n_hits_got].type, SERV_TypeStr(info->type)); strcpy(s_hits_got[s_n_hits_got].xtra, (info->type & fSERV_Http) ? SERV_HTTP_PATH(&info->u.http) : ""); strcpy(s_hits_got[s_n_hits_got].loc , (info->site & fSERV_Local ) ? "yes" : "no"); strcpy(s_hits_got[s_n_hits_got].priv, (info->site & fSERV_Private ) ? "yes" : "no"); strcpy(s_hits_got[s_n_hits_got].stfl, (info->mode & fSERV_Stateful) ? "yes" : "no"); SOCK_ntoa(info->host, s_hits_got[s_n_hits_got].host, LEN_HOST); s_hits_got[s_n_hits_got].port = info->port; s_hits_got[s_n_hits_got].match = 0; char *info_str; info_str = SERV_WriteInfo(info); CORE_LOGF(eLOG_Note, (" Found server %d: %s", s_n_hits_got, info_str ? info_str : "?")); if (info_str) free(info_str); } /* Make sure endpoint data can be repopulated and reset. */ if (repop && s_n_hits_got) { /* repopulate */ CORE_LOG(eLOG_Trace, "Repopulating the service mapper."); if ( ! info && ! SERV_GetNextInfo(iter)) { CORE_LOG(eLOG_Error, "Unable to repopulate endpoint data."); errors = 1; } } if (reset && s_n_hits_got) { /* reset */ CORE_LOG(eLOG_Trace, "Resetting the service mapper."); SERV_Reset(iter); if ( ! SERV_GetNextInfo(iter)) { CORE_LOG(eLOG_Error, "No services found after reset."); errors = 1; } } SERV_Close(iter); } else { errors = 1; } /* Search for matches unless this is a standalone run. */ if (check_for_match) { /* Search for perfect matches first (order is unknown). */ int it_exp, it_got; for (it_got=0; it_got < s_n_hits_got; ++it_got) { for (it_exp=0; it_exp < s_n_hits_exp; ++it_exp) { if (s_hits_exp[it_exp].match) continue; /*if (check_match(fMatch_Default, it_exp, it_got)) {*/ if (check_match(fMatch_All, it_exp, it_got)) { CORE_LOGF(eLOG_Note, ( " Found server %d perfectly matched expected server " "%d.", it_got, it_exp)); s_hits_exp[it_exp].match = 1; s_hits_got[it_got].match = 1; ++n_matches_perfect; break; } } } /* If not all found, search again but exclude host:port from match. */ for (it_got=0; it_got < s_n_hits_got; ++it_got) { if (s_hits_got[it_got].match) continue; for (it_exp=0; it_exp < s_n_hits_exp; ++it_exp) { if (s_hits_exp[it_exp].match) continue; if (check_match(fMatch_NoHostPort, it_exp, it_got)) { CORE_LOGF(eLOG_Note, ( " Found server %d nearly matched expected server %d.", it_got, it_exp)); s_hits_exp[it_exp].match = 1; s_hits_got[it_got].match = 1; ++n_matches_near; log_match_diffs(it_exp, it_got); break; } } } /* List any non-matching servers. */ for (it_exp=0; it_exp < s_n_hits_exp; ++it_exp) { if ( ! s_hits_exp[it_exp].match) CORE_LOGF(eLOG_Note, ( " Expected server %d didn't match any found servers.", it_exp)); } for (it_got=0; it_got < s_n_hits_got; ++it_got) { if ( ! s_hits_got[it_got].match) CORE_LOGF(eLOG_Note, ( " Found server %d didn't match any expected servers.", it_got)); } CORE_LOGF(n_matches_perfect + n_matches_near == s_n_hits_got ? eLOG_Note : eLOG_Error, ("Expected %d servers; found %d (%d perfect matches, %d near " "matches, and %d non-matches).", s_n_hits_exp, s_n_hits_got, n_matches_perfect, n_matches_near, s_n_hits_got - n_matches_perfect - n_matches_near)); if (!errors && s_n_hits_got == s_n_hits_exp && s_n_hits_got == n_matches_perfect + n_matches_near) { success = 1; } retval = (success != exp_err ? 1 : 0); CORE_LOGF(eLOG_Note, ("Test result: %s.", retval ? (success ? "PASS" : "PASS (with expected error)") : (success ? "FAIL (success when error expected)" : "FAIL"))); } out: if (mock_body_adj) free(mock_body_adj); return retval == -1 ? (success != exp_err ? 1 : 0) : retval; }
/* One can define env.var. 'service'_CONN_HOST to reroute dispatching * information to particular dispatching host (instead of default). */ int main(int argc, const char* argv[]) { static const char kParameter[] = "test_parameter"; const char* service = argc > 1 ? argv[1] : "bounce"; SConnNetInfo* net_info; const SSERV_Info* info; const char* value; int n_found = 0; SERV_ITER iter; CORE_SetLOGFormatFlags(fLOG_None | fLOG_Level | fLOG_OmitNoteLevel | fLOG_DateTime); CORE_SetLOGFILE(stderr, 0/*false*/); if (argc > 2) { if (strcasecmp(argv[2],"heap") == 0 || strcasecmp(argv[2],"all") == 0){ HEAP_Options(eOff, eDefault); CORE_LOG(eLOG_Note, "Using slow heap access (w/checks)"); } if (strcasecmp(argv[2],"lbsm") == 0 || strcasecmp(argv[2],"all") == 0){ #ifdef NCBI_OS_MSWIN if (strcasecmp(argv[2],"lbsm") == 0) { CORE_LOG(eLOG_Warning, "Option \"lbsm\" has no useful effect on MS-Windows"); } #else LBSMD_FastHeapAccess(eOn); CORE_LOG(eLOG_Note, "Using live (faster) LBSM heap access"); #endif /*NCBI_OS_MSWIN*/ } if (strcasecmp(argv[2],"lbsm") != 0 && strcasecmp(argv[2],"heap") != 0 && strcasecmp(argv[2],"all") != 0) CORE_LOGF(eLOG_Fatal, ("Unknown option `%s'", argv[2])); } value = LBSMD_GetHostParameter(SERV_LOCALHOST, kParameter); CORE_LOGF(eLOG_Note, ("Querying host parameter `%s': %s%s%s", kParameter, "`" + !value, value ? value : "Not found", "'" + !value)); if (value) free((void*) value); CORE_LOGF(eLOG_Note, ("Looking for service `%s'", service)); net_info = ConnNetInfo_Create(service); CORE_LOG(eLOG_Trace, "Opening service mapper"); iter = SERV_OpenP(service, (fSERV_All & ~fSERV_Firewall) | (strpbrk(service, "?*") ? fSERV_Promiscuous : 0), SERV_LOCALHOST, 0/*port*/, 0.0/*preference*/, net_info, 0/*skip*/, 0/*n_skip*/, 0/*external*/, 0/*arg*/, 0/*val*/); ConnNetInfo_Destroy(net_info); if (iter) { HOST_INFO hinfo; CORE_LOGF(eLOG_Trace,("%s service mapper has been successfully opened", SERV_MapperName(iter))); while ((info = SERV_GetNextInfoEx(iter, &hinfo)) != 0) { char* info_str = SERV_WriteInfo(info); CORE_LOGF(eLOG_Note, ("Server #%d `%s' = %s", ++n_found, SERV_CurrentName(iter), info_str)); if (hinfo) { static const char kTimeFormat[] = "%m/%d/%y %H:%M:%S"; time_t t; char buf[80]; double array[5]; SHINFO_Params params; const char* e = HINFO_Environment(hinfo); const char* a = HINFO_AffinityArgument(hinfo); const char* v = HINFO_AffinityArgvalue(hinfo); CORE_LOG(eLOG_Note, " Host info available:"); CORE_LOGF(eLOG_Note, (" Number of CPUs: %d", HINFO_CpuCount(hinfo))); CORE_LOGF(eLOG_Note, (" Number of CPU units: %d @ %.0fMHz", HINFO_CpuUnits(hinfo), HINFO_CpuClock(hinfo))); CORE_LOGF(eLOG_Note, (" Number of tasks: %d", HINFO_TaskCount(hinfo))); if (HINFO_MachineParams(hinfo, ¶ms)) { CORE_LOGF(eLOG_Note, (" Arch: %d", params.arch)); CORE_LOGF(eLOG_Note, (" OSType: %d", params.ostype)); t = (time_t) params.bootup; strftime(buf, sizeof(buf), kTimeFormat, localtime(&t)); CORE_LOGF(eLOG_Note, (" Kernel: %hu.%hu.%hu @ %s", params.kernel.major, params.kernel.minor, params.kernel.patch, buf)); CORE_LOGF(eLOG_Note, (" Bits: %hu", params.bits)); CORE_LOGF(eLOG_Note, (" Page size: %lu", (unsigned long) params.pgsize)); t = (time_t) params.start; strftime(buf, sizeof(buf), kTimeFormat, localtime(&t)); CORE_LOGF(eLOG_Note, (" LBSMD: %hu.%hu.%hu @ %s", params.daemon.major, params.daemon.minor, params.daemon.patch, buf)); } else CORE_LOG (eLOG_Note, " Machine params: unavailable"); if (HINFO_Memusage(hinfo, array)) { CORE_LOGF(eLOG_Note, (" Total RAM: %.2fMB", array[0])); CORE_LOGF(eLOG_Note, (" Cache RAM: %.2fMB", array[1])); CORE_LOGF(eLOG_Note, (" Free RAM: %.2fMB", array[2])); CORE_LOGF(eLOG_Note, (" Total Swap: %.2fMB", array[3])); CORE_LOGF(eLOG_Note, (" Free Swap: %.2fMB", array[4])); } else CORE_LOG (eLOG_Note, " Memory usage: unavailable"); if (HINFO_LoadAverage(hinfo, array)) { CORE_LOGF(eLOG_Note, (" Load averages: %f, %f (BLAST)", array[0], array[1])); } else CORE_LOG (eLOG_Note, " Load averages: unavailable"); if (a) { assert(*a); CORE_LOGF(eLOG_Note, (" Affinity argument: %s", a)); } if (a && v) CORE_LOGF(eLOG_Note, (" Affinity value: %s%s%s", *v ? "" : "\"", v, *v ? "" : "\"")); CORE_LOGF(eLOG_Note, (" Host environment: %s%s%s", e? "\"": "", e? e: "NULL", e? "\"": "")); free(hinfo); } free(info_str); } CORE_LOG(eLOG_Trace, "Resetting service mapper"); SERV_Reset(iter); CORE_LOG(eLOG_Trace, "Service mapper has been reset"); if (n_found && !(info = SERV_GetNextInfo(iter))) CORE_LOG(eLOG_Fatal, "Service not found after reset"); CORE_LOG(eLOG_Trace, "Closing service mapper"); SERV_Close(iter); } if (n_found != 0) CORE_LOGF(eLOG_Note, ("%d server(s) found", n_found)); else CORE_LOG(eLOG_Fatal, "Requested service not found"); #if 0 {{ SConnNetInfo* net_info; net_info = ConnNetInfo_Create(service); iter = SERV_Open(service, fSERV_Http, SERV_LOCALHOST, net_info); ConnNetInfo_Destroy(net_info); }} if (iter != 0) { while ((info = SERV_GetNextInfo(iter)) != 0) { char* info_str = SERV_WriteInfo(info); CORE_LOGF(eLOG_Note, ("Service `%s' = %s", service, info_str)); free(info_str); n_found++; } SERV_Close(iter); } #endif CORE_LOG(eLOG_Note, "TEST completed successfully"); CORE_SetLOG(0); return 0; }