unsigned short SERV_ServerPort(const char* name, unsigned int host) { SSERV_Info* info; unsigned short port; /* FIXME: SERV_LOCALHOST may not need to be resolved here, * but taken from LBSMD table (or resolved later in DISPD/LOCAL * if needed). */ if (!host || host == SERV_LOCALHOST) host = SOCK_GetLocalHostAddress(eDefault); if (!(info = s_GetInfo(name, fSERV_Standalone | fSERV_Promiscuous, host, 0/*pref. port*/, -1.0/*latch host*/, 0/*net_info*/, 0/*skip*/, 0/*n_skip*/, 0/*not external*/, 0/*arg*/, 0/*val*/, 0/*host_info*/))) { return 0; } assert(info->host == host); port = info->port; free((void*) info); assert(port); return port; }
static int/*bool*/ s_LoadSingleService(const char* name, SERV_ITER iter) { struct SLOCAL_Data* data = (struct SLOCAL_Data*) iter->data; const TSERV_Type types = iter->types & ~fSERV_Firewall; char key[sizeof(REG_CONN_LOCAL_SERVER) + 10]; int/*bool*/ ok = 0/*failed*/; SSERV_Info* info; int n; info = 0; strcpy(key, REG_CONN_LOCAL_SERVER "_"); for (n = 0; n <= 100; n++) { const char* svc; char buf[1024]; if (info) { free((void*) info); info = 0; } sprintf(key + sizeof(REG_CONN_LOCAL_SERVER), "%d", n); if (!(svc = ConnNetInfo_GetValue(name, key, buf, sizeof(buf), 0))) continue; if (!(info = SERV_ReadInfoEx (svc, iter->ismask || iter->reverse_dns ? name : "", 0))) { continue; } if (iter->external && (info->site & (fSERV_Local | fSERV_Private))) continue; /* external mapping for local server not allowed */ if (!info->host || (info->site & fSERV_Private)) { unsigned int localhost = SOCK_GetLocalHostAddress(eDefault); if (!info->host) info->host = localhost; if ((info->site & fSERV_Private) && info->host != localhost) continue; /* private server */ } if (!iter->reverse_dns && info->type != fSERV_Dns) { if (types != fSERV_Any && !(types & info->type)) continue; /* type doesn't match */ if (types == fSERV_Any && info->type == fSERV_Dns) continue; /* DNS entries have to be req'd explicitly */ if (iter->stateless && (info->mode & fSERV_Stateful)) continue; /* skip stateful only servers */ } if (!info->rate) info->rate = LBSM_DEFAULT_RATE; if (!info->time) info->time = LBSM_DEFAULT_TIME; if (!s_AddService(info, data)) break; info = 0; ok = 1/*succeeded*/; } if (info) free((void*) info); return ok/*whatever*/; }
static unsigned int s_GetLocalHostAddress(HEAP heap) { unsigned int localhost; const SLBSM_Version* v = (const SLBSM_Version*) HEAP_Base(heap); assert(v->entry.type == eLBSM_Version); if (!(localhost = s_Localhost(v))) localhost = SOCK_GetLocalHostAddress(eDefault); return localhost; }
int/*bool*/ SERV_MatchesHost(const SSERV_Info* info, unsigned int host) { if (host == SERV_ANYHOST) return 1/*true*/; if (host != SERV_LOCALHOST) return info->host == host ? 1/*true*/ : 0/*false*/; if (!info->host || info->host == SOCK_GetLocalHostAddress(eDefault)) return 1/*true*/; return 0/*false*/; }
extern int g_NCBI_ConnectSrandAddend(void) { #if defined(NCBI_OS_UNIX) return (int) getpid(); #elif defined(NCBI_OS_MSWIN) return (int) GetCurrentProcessId(); #else return SOCK_GetLocalHostAddress(eDefault); #endif /*NCBI_OS_...*/ }
static int/*bool*/ s_IsSkipHost(unsigned int host, unsigned int skip_host) { return skip_host == host || (skip_host == SERV_LOCALHOST && host == SOCK_GetLocalHostAddress(eDefault)); }
static int/*bool*/ s_LoadSingleService(const char* name, SERV_ITER iter) { struct SLOCAL_Data* data = (struct SLOCAL_Data*) iter->data; const TSERV_Type type = iter->type & ~fSERV_Firewall; int/*bool*/ ok = 0/*failed*/; SSERV_Info* info; char* buf; int n; if (!(buf = (char*) malloc(strlen(name) + sizeof(REG_CONN_LOCAL_SERVER) + 80))) { return 0/*failed*/; } info = 0; for (n = 0; n <= 100; n++) { char service[1024]; const char* c; if (info) { free((void*) info); info = 0; } sprintf(buf, "%s_" REG_CONN_LOCAL_SERVER "_%d", name, n); if (!(c = getenv(buf)) && !(c = getenv(strupr(buf)))) { char* b = buf + strlen(name); size_t len; *b++ = '\0'; CORE_REG_GET(buf, b, service, sizeof(service) - 1, 0); len = strlen(service); if (len > 1 && (service[0] == '"' || service[0] == '\'') && service[len - 1] == service[0] && (len -= 2) > 0) { memmove(service, service + 1, len); service[len] = '\0'; } if (!len) continue; c = service; } if (!(info = SERV_ReadInfoEx (c, iter->ismask || iter->reverse_dns ? name : ""))) { continue; } if (iter->external && info->locl) continue; /* external mapping for local server not allowed */ if (!info->host || (info->locl & 0xF0)) { unsigned int localhost = SOCK_GetLocalHostAddress(eDefault); if (!info->host) info->host = localhost; if ((info->locl & 0xF0) && info->host != localhost) continue; /* private server */ } if (!iter->reverse_dns && info->type != fSERV_Dns) { if (type != fSERV_Any && !(type & info->type)) continue; /* type doesn't match */ if (type == fSERV_Any && info->type == fSERV_Dns) continue; /* DNS entries have to be req'd explicitly */ if (iter->stateless && info->sful && !(info->type & fSERV_Http)) continue; /* skip stateful only servers */ } if (!info->rate) info->rate = LBSM_DEFAULT_RATE; if (!info->time) info->time = LBSM_DEFAULT_TIME; if (!s_AddService(info, data)) break; info = 0; ok = 1/*succeeded*/; } if (info) free((void*) info); free(buf); return ok/*whatever*/; }
static SERV_ITER s_Open(const char* service, unsigned/*bool*/ ismask, TSERV_Type types, unsigned int preferred_host, unsigned short preferred_port, double preference, const SConnNetInfo* net_info, const SSERV_InfoCPtr skip[], size_t n_skip, unsigned/*bool*/ external, const char* arg, const char* val, SSERV_Info** info, HOST_INFO* host_info) { int/*bool*/ do_lbsmd = -1/*unassigned*/, do_dispd = -1/*unassigned*/; const SSERV_VTable* op; SERV_ITER iter; const char* s; if (!(s = s_ServiceName(service, ismask, 0))) return 0; if (!(iter = (SERV_ITER) calloc(1, sizeof(*iter)))) { free((void*) s); return 0; } assert(ismask || *s); iter->name = s; iter->type = types & fSERV_All; iter->host = (preferred_host == SERV_LOCALHOST ? SOCK_GetLocalHostAddress(eDefault) : preferred_host); iter->port = preferred_port; iter->pref = (preference < 0.0 ? -1.0 : 0.01 * (preference > 100.0 ? 100.0 : preference)); if (ismask) iter->ismask = 1; if (types & fSERV_IncludeDown) iter->ok_down = 1; if (types & fSERV_IncludeSuppressed) iter->ok_suppressed = 1; if (types & fSERV_ReverseDns) iter->reverse_dns = 1; if (types & fSERV_Stateless) iter->stateless = 1; iter->external = external; if (arg && *arg) { iter->arg = arg; iter->arglen = strlen(arg); if (val) { iter->val = val; iter->vallen = strlen(val); } } iter->time = (TNCBI_Time) time(0); if (n_skip) { size_t i; for (i = 0; i < n_skip; i++) { const char* name = (iter->ismask || skip[i]->type == fSERV_Dns ? SERV_NameOfInfo(skip[i]) : ""); SSERV_Info* temp = SERV_CopyInfoEx(skip[i], !iter->reverse_dns || *name ? name : s); if (temp) { temp->time = NCBI_TIME_INFINITE; if (!s_AddSkipInfo(iter, name, temp)) { free(temp); temp = 0; } } if (!temp) { SERV_Close(iter); return 0; } } } assert(n_skip == iter->n_skip); if (net_info) { if (net_info->firewall) iter->type |= fSERV_Firewall; if (net_info->stateless) iter->stateless = 1; if (net_info->lb_disable) do_lbsmd = 0/*false*/; } else do_dispd = 0/*false*/; /* Ugly optimization not to access the registry more than necessary */ if ((!s_IsMapperConfigured(service, REG_CONN_LOCAL_ENABLE) || !(op = SERV_LOCAL_Open(iter, info, host_info))) && (!do_lbsmd || !(do_lbsmd= !s_IsMapperConfigured(service, REG_CONN_LBSMD_DISABLE)) || !(op = SERV_LBSMD_Open(iter, info, host_info, !do_dispd || !(do_dispd = !s_IsMapperConfigured (service, REG_CONN_DISPD_DISABLE))))) && (!do_dispd || !(do_dispd= !s_IsMapperConfigured(service, REG_CONN_DISPD_DISABLE)) || !(op = SERV_DISPD_Open(iter, net_info, info, host_info)))) { if (!do_lbsmd && !do_dispd) { CORE_LOGF_X(1, eLOG_Error, ("[%s] No service mappers available", service)); } SERV_Close(iter); return 0; } assert(op != 0); iter->op = op; return iter; }