NCBI C++ ToolKit
ncbi_service.c
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: ncbi_service.c 100095 2023-06-15 04:35:16Z lavr $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Author: Anton Lavrentiev
27  *
28  * File Description:
29  * Top-level API to resolve NCBI service name to the server meta-address.
30  *
31  */
32 
33 #include "ncbi_ansi_ext.h"
34 #include "ncbi_dispd.h"
35 #ifdef NCBI_OS_UNIX
36 # include "ncbi_lbsmd.h"
37 #endif /*NCBI_OS_UNIX*/
38 #include "ncbi_local.h"
39 #ifdef NCBI_CXX_TOOLKIT
40 # include "ncbi_lbdns.h"
41 # include "ncbi_linkerd.h"
42 # include "ncbi_namerd.h"
43 #endif /*NCBI_CXX_TOOLKIT*/
44 #include "ncbi_priv.h"
45 #include <ctype.h>
46 #include <stdlib.h>
47 #include <time.h>
48 
49 #define NCBI_USE_ERRCODE_X Connect_Service
50 
51 
52 /*
53  * FIXME FIXME FIXME FIXME FIXME ---->
54  *
55  * NOTE: For fSERV_ReverseDns lookups the following rules apply to "skip"
56  * contents: a service would not be selected if there is a same-named
57  * entry with matching host[:port] is found in the "skip" list, or
58  * there is a nameless...
59  * NOTE: Lookup by mask cancels fSERV_ReverseDns mode, if both are used.
60  */
61 
62 
63 #define SERV_SERVICE_NAME_RECURSION_MAX 10
64 #define CONN_IMPLICIT_SERVER_TYPE DEF_CONN_REG_SECTION \
65  "_" REG_CONN_IMPLICIT_SERVER_TYPE
66 
67 static ESwitch s_Fast = eOff;
68 
69 
70 #if 0
71 static char* x_getenv(const char* name)
72 {
73  char* env = getenv(name);
74  CORE_TRACEF(("getenv(\"%s\") = %s%s%s", name,
75  &"\""[!env], env ? env : "NULL", &"\""[!env]));
76  return env;
77 }
78 #else
79 # define x_getenv getenv
80 #endif
81 
82 
83 static int/*bool*/ x_tr(char* str, char a, char b, size_t len)
84 {
85  int/*bool*/ done = 0/*false*/;
86  char* end = str + len;
87  while (str < end) {
88  if (*str == a) {
89  *str = b;
90  done = 1/*true*/;
91  }
92  ++str;
93  }
94  return done;
95 }
96 
97 
98 /* "service" == the original input service name;
99  * "svc" == current service name (== "service" at first);
100  * "ismask" = 1 if "service" may contain any wildcards;
101  * "*isfast" = 1 on input if not to do environment scan;
102  * "*isfast" = 1 on output if the service was substituted with itself (but may
103  * be different case); otherwise, "*isfast" == 0. This is used
104  * (only) in namerd searches, which are case-sensitive.
105  */
106 static char* x_ServiceName(unsigned int depth,
107  const char* service, const char* svc,
108  int/*bool*/ ismask, int* /*bool*/isfast)
109 {
110  char buf[128];
111  size_t len = 0;
112 
113  assert(isfast);
114  assert(!svc == !service);
115  assert(depth || svc == service);
116  assert(sizeof(buf) > sizeof(REG_CONN_SERVICE_NAME));
117  if (!svc || (!ismask && (!*svc || strpbrk(svc, "?*[")))
118  || (len = strlen(svc)) >= sizeof(buf)-sizeof(REG_CONN_SERVICE_NAME)
119  || NCBI_HasSpaces(svc, len)) {
120  if (!service || strcasecmp(service, svc) == 0)
121  service = "";
123  ("%s%s%s%s service name%s%s",
124  !svc || !*svc ? "" : "[",
125  !svc ? "" : svc,
126  !svc || !*svc ? "" : "] ",
127  !svc ? "NULL" : !*svc ? "Empty"
128  : len < sizeof(buf) - sizeof(REG_CONN_SERVICE_NAME)
129  ? "Invalid" : "Too long",
130  *service ? " for: " : "", service));
131  return 0/*failure*/;
132  }
133  if (!ismask && !*isfast) {
134  char tmp[sizeof(buf)];
135  int/*bool*/ tr = x_tr((char*) memcpy(tmp, svc, len), '-', '_', len);
136  char* s = tmp + len;
137  *s++ = '_';
138  memcpy(s, REG_CONN_SERVICE_NAME, sizeof(REG_CONN_SERVICE_NAME));
139  len += 1 + sizeof(REG_CONN_SERVICE_NAME);
140  /* Looking for "svc_CONN_SERVICE_NAME" in the environment */
141  if ((!(s = x_getenv(strupr((char*) memcpy(buf, tmp, len--))))
142  && (memcmp(buf, tmp, len) == 0 || !(s = x_getenv(tmp))))
143  || !*s) {
144  /* Looking for "CONN_SERVICE_NAME" in registry section "[svc]" */
145  len -= sizeof(REG_CONN_SERVICE_NAME);
146  if (tr)
147  memcpy(buf, svc, len); /* re-copy */
148  buf[len++] = '\0';
149  if (CORE_REG_GET(buf, buf + len, tmp, sizeof(tmp), 0))
150  strcpy(buf, tmp);
151  else
152  *buf = '\0';
153  s = buf;
154  }
155  if (*s) {
156  CORE_TRACEF(("[%s] CONN_ServiceName(\"%s\"): \"%s\"",
157  service, svc, s));
158  if (strcasecmp(svc, s) != 0) {
160  return x_ServiceName(depth, service, s, ismask, isfast);
162  ("[%s] Maximal service name recursion"
163  " depth exceeded: %u", service, depth));
164  return 0/*failure*/;
165  } else
166  svc = s, *isfast = 1/*true*/;
167  } else
168  *isfast = 0/*false*/;
169  } else
170  *isfast = 0/*false*/;
171  return strdup(svc);
172 }
173 
174 
175 static char* s_ServiceName(const char* service,
176  int/*bool*/ ismask, int* /*bool*/isfast)
177 {
178  char* retval;
180  retval = x_ServiceName(0/*depth*/, service, service, ismask, isfast);
181  CORE_UNLOCK;
182  return retval;
183 }
184 
185 
186 char* SERV_ServiceName(const char* service)
187 {
188  int dummy = 0;
189  return s_ServiceName(service, 0/*ismask*/, &dummy/*isfast*/);
190 }
191 
192 
193 static int/*bool*/ s_AddSkipInfo(SERV_ITER iter,
194  const char* name,
196 {
197  size_t n;
198  assert(name);
199  for (n = 0; n < iter->n_skip; n++) {
200  if (strcasecmp(name, SERV_NameOfInfo(iter->skip[n])) == 0
201  && (SERV_EqualInfo(info, iter->skip[n]) ||
202  (iter->skip[n]->type == fSERV_Firewall &&
203  iter->skip[n]->u.firewall.type == info->u.firewall.type))) {
204  /* Replace older version */
205  if (iter->last == iter->skip[n])
206  iter->last = info;
207  free((void*) iter->skip[n]);
208  iter->skip[n] = info;
209  return 1;
210  }
211  }
212  if (iter->n_skip == iter->a_skip) {
213  SSERV_InfoCPtr* temp;
214  n = iter->a_skip + 10;
215  temp = (SSERV_InfoCPtr*)
216  (iter->skip
217  ? realloc((void*) iter->skip, n * sizeof(*temp))
218  : malloc ( n * sizeof(*temp)));
219  if (!temp)
220  return 0;
221  iter->skip = temp;
222  iter->a_skip = n;
223  }
224  iter->skip[iter->n_skip++] = info;
225  return 1;
226 }
227 
228 
229 #ifdef __GNUC__
230 inline
231 #endif /*__GNUC__*/
232 static int/*bool*/ x_IsMapperConfigured(const char* svc,
233  const char* key,
234  int/*bool*/ fast)
235 {
236  char val[40];
237  return fast
238  ? 0/*false*/
240  (svc, key, val, sizeof(val), 0));
241 }
242 
243 
244 #define s_IsMapperConfigured(s, k) x_IsMapperConfigured(s, k, s_Fast)
245 
246 
247 int/*bool*/ SERV_IsMapperConfiguredInternal(const char* svc, const char* key)
248 {
249  return s_IsMapperConfigured(svc, key);
250 }
251 
252 
253 static SERV_ITER x_Open(const char* service,
254  int/*bool*/ ismask,
256  unsigned int preferred_host,
257  unsigned short preferred_port,
258  double preference,
259  const SConnNetInfo* net_info,
260  SSERV_InfoCPtr skip[],
261  size_t n_skip,
262  int/*bool*/ external,
263  const char* arg,
264  const char* val,
265  SSERV_Info** info,
266  HOST_INFO* host_info)
267 {
268  int/*bool*/
269  do_local,
270 #ifdef NCBI_OS_UNIX
271  do_lbsmd = -1/*unassigned*/,
272 #endif /*NCBI_OS_UNIX*/
273 #ifdef NCBI_CXX_TOOLKIT
274 # ifdef NCBI_OS_UNIX
275  do_lbdns = -1/*unassigned*/,
276 # endif /*NCBI_OS_UNIX*/
277  do_linkerd = -1/*unassigned*/,
278  do_namerd = -1/*unassigned*/,
279 #endif /*NCBI_CXX_TOOLKIT*/
280  do_dispd = -1/*unassigned*/;
281  const SSERV_VTable* op;
282  int exact = s_Fast;
283  const char* svc;
284  SERV_ITER iter;
285 
286  if (!(svc = s_ServiceName(service, ismask, &exact)))
287  return 0;
288  assert(ismask || *svc);
289  if (!(iter = (SERV_ITER) calloc(1, sizeof(*iter)))) {
290  free((void*) svc);
291  return 0;
292  }
293 
294  iter->name = svc;
295  iter->host = (preferred_host == SERV_LOCALHOST
297  : preferred_host);
298  iter->port = preferred_port;
299  iter->pref = (preference < 0.0
300  ? -1.0
301  : 0.01 * (preference > 100.0
302  ? 100.0
303  : preference));
304  iter->types = (TSERV_TypeOnly) types;
305  if (ismask)
306  iter->ismask = 1;
307  if (types & fSERV_IncludeDown)
308  iter->ok_down = 1;
310  iter->ok_standby = 1;
312  iter->ok_private = 1;
314  iter->ok_reserved = 1;
316  iter->ok_suppressed = 1;
317  if (types & fSERV_ReverseDns)
318  iter->reverse_dns = 1;
319  iter->external = external ? 1 : 0;
320  iter->exact = exact;
321  if (arg && *arg) {
322  iter->arg = arg;
323  iter->arglen = strlen(arg);
324  if (val) {
325  iter->val = val;
326  iter->vallen = strlen(val);
327  }
328  }
329  iter->time = (TNCBI_Time) time(0);
330  if (ismask)
331  svc = 0;
332 
333  if (n_skip) {
334  size_t i;
335  for (i = 0; i < n_skip; ++i) {
336  const char* name = (iter->ismask || skip[i]->type == fSERV_Dns
337  ? SERV_NameOfInfo(skip[i]) : "");
338  SSERV_Info* temp = SERV_CopyInfoEx(skip[i],
339  iter->reverse_dns && !*name ?
340  iter->name : name );
341  if (temp) {
342  temp->time = NCBI_TIME_INFINITE;
343  if (!s_AddSkipInfo(iter, name, temp)) {
344  free(temp);
345  temp = 0;
346  }
347  }
348  if (!temp) {
349  SERV_Close(iter);
350  return 0;
351  }
352  }
353  }
354  assert(n_skip == iter->n_skip);
355  iter->o_skip = iter->n_skip;
356 
357  if (net_info) {
358  if (net_info->external)
359  iter->external = 1;
360  if (net_info->firewall)
361  iter->types |= fSERV_Firewall;
362  if (net_info->stateless)
363  iter->types |= fSERV_Stateless;
364 #ifdef NCBI_OS_UNIX
365  if (net_info->lb_disable)
366  do_lbsmd = 0/*false*/;
367 #endif /*NCBI_OS_UNIX*/
368  } else {
369 #ifdef NCBI_CXX_TOOLKIT
370  do_linkerd = do_namerd =
371 #endif /*NCBI_CXX_TOOLKIT*/
372  do_dispd = 0/*false*/;
373  }
374  if (host_info)
375  *host_info = 0;
376  /* Ugly optimization not to access the registry more than necessary */
377  if ((!(do_local = s_IsMapperConfigured(svc, REG_CONN_LOCAL_ENABLE)) ||
378  !(op = SERV_LOCAL_Open(iter, info)))
379 
380 #ifdef NCBI_OS_UNIX
381  &&
382  (!do_lbsmd ||
383  !(do_lbsmd = !s_IsMapperConfigured(svc, REG_CONN_LBSMD_DISABLE)) ||
384  !(op = SERV_LBSMD_Open(iter, info, host_info,
385  (!do_dispd ||
386  !(do_dispd = !s_IsMapperConfigured
387  (svc, REG_CONN_DISPD_DISABLE)))
388 # ifdef NCBI_CXX_TOOLKIT
389 # ifdef NCBI_OS_UNIX
390  &&
391  !(do_lbdns = s_IsMapperConfigured
392  (svc, REG_CONN_LBDNS_ENABLE))
393 # endif /*NCBI_OS_UNIX*/
394  &&
395  (!do_linkerd ||
396  !(do_linkerd = s_IsMapperConfigured
397  (svc, REG_CONN_LINKERD_ENABLE)))
398  &&
399  (!do_namerd ||
400  !(do_namerd = s_IsMapperConfigured
401  (svc, REG_CONN_NAMERD_ENABLE)))
402 # endif /*NCBI_CXX_TOOLKIT*/
403  )))
404 #endif /*NCBI_OS_UNIX*/
405 
406 #ifdef NCBI_CXX_TOOLKIT
407 # ifdef NCBI_OS_UNIX
408  &&
409  (!do_lbdns ||
410  (do_lbdns < 0 && !(do_lbdns = s_IsMapperConfigured
411  (svc, REG_CONN_LBDNS_ENABLE))) ||
412  !(op = SERV_LBDNS_Open(iter, info)))
413 # endif /*NCBI_OS_UNIX*/
414  &&
415  (!do_linkerd ||
416  (do_linkerd < 0 && !(do_linkerd = s_IsMapperConfigured
417  (svc, REG_CONN_LINKERD_ENABLE))) ||
418  !(op = SERV_LINKERD_Open(iter, net_info, info, &do_namerd)))
419  &&
420  (!do_namerd ||
421  (do_namerd < 0 && !(do_namerd = s_IsMapperConfigured
422  (svc, REG_CONN_NAMERD_ENABLE))) ||
423  !(op = SERV_NAMERD_Open(iter, net_info, info)))
424 #endif /*NCBI_CXX_TOOLKIT*/
425 
426  &&
427  (!do_dispd ||
428  (do_dispd < 0 && !(do_dispd = !s_IsMapperConfigured
429  (svc, REG_CONN_DISPD_DISABLE))) ||
430  !(op = SERV_DISPD_Open(iter, net_info, info)))) {
431  if (!s_Fast && net_info
432  && !do_local
433 #ifdef NCBI_OS_UNIX
434  && !do_lbsmd
435 #endif /*NXBI_OS_UNIX*/
436 #ifdef NCBI_CXX_TOOLKIT
437 # ifdef NCBI_OS_UNIX
438  && !do_lbdns
439 # endif /*NCBI_OS_UNIX*/
440  && !do_linkerd && !do_namerd
441 #endif /*NCBI_CXX_TOOLKIT*/
442  && !do_dispd
443  ) {
444  if (svc && strcasecmp(service, svc) == 0)
445  svc = 0;
446  assert(*service || !svc);
448  ("%s%s%s%s%sNo service mappers available",
449  &"["[!*service], service,
450  &"/"[!svc], svc ? svc : "",
451  *service ? "] " : ""));
452  }
453  SERV_Close(iter);
454  return 0;
455  }
456 
457  assert(op != 0);
458  iter->op = op;
459  return iter;
460 }
461 
462 
463 static void s_SkipSkip(SERV_ITER iter)
464 {
465  size_t n;
466  if (iter->time && (iter->ismask | iter->ok_down | iter->ok_suppressed))
467  return;
468  n = 0;
469  while (n < iter->n_skip) {
470  SSERV_InfoCPtr temp = iter->skip[n];
471  if (temp != iter->last && temp->time != NCBI_TIME_INFINITE
472  && (!iter->time/*iterator reset*/
473  || ((temp->type != fSERV_Dns || temp->host)
474  && temp->time < iter->time))) {
475  if (--iter->n_skip > n) {
476  SSERV_InfoCPtr* ptr = iter->skip + n;
477  memmove((void*) ptr, (void*)(ptr + 1),
478  (iter->n_skip - n) * sizeof(*ptr));
479  }
480  free((void*) temp);
481  } else
482  n++;
483  }
484 }
485 
486 
487 #if defined(_DEBUG) && !defined(NDEBUG)
488 
489 #define x_RETURN(retval) return x_Return((SSERV_Info*) info, infostr, retval)
490 
491 
492 # ifdef __GNUC__
493 inline
494 # endif /*__GNUC__*/
495 static int/*bool*/ x_Return(SSERV_Info* info,
496  const char* infostr,
497  int/*bool*/ retval)
498 {
499  if (infostr)
500  free((void*) infostr);
501  if (!retval)
502  free(info);
503  return retval;
504 }
505 
506 
507 /* Do some basic set of consistency checks for the returned server info.
508  * Return 0 if failed (also free(info) if so); return 1 if passed. */
509 static int/*bool*/ x_ConsistencyCheck(SERV_ITER iter, const SSERV_Info* info)
510 {
511  const char* name = SERV_NameOfInfo(info);
512  const char* infostr = SERV_WriteInfo(info);
514  size_t n;
515 
516  if (!name) {
518  ("[%s] NULL name @%p\n%s", iter->name, info,
519  infostr ? infostr : "<NULL>"));
520  x_RETURN(0/*failure*/);
521  }
522  if (!(iter->ismask | iter->reverse_dns) != !*name) {
524  ("[%s] %s name \"%s\" @%p\n%s", iter->name,
525  *name ? "Unexpected" : "Empty", name,
526  info, infostr ? infostr : "<NULL>"));
527  x_RETURN(0/*failure*/);
528  }
529  if (!info->host || !info->port) {
530  if (info->type != fSERV_Dns) {
532  ("[%s] Non-DNS server with empty %s @%p:\n%s",
533  iter->name, !(info->host | info->port) ? "host:port"
534  : info->host ? "port" : "host",
535  info, infostr ? infostr : "<NULL>"));
536  x_RETURN(0/*failure*/);
537  }
538  if (!info->host && (iter->last || iter->ismask)) {
540  ("[%s] Interim DNS server w/o host @%p:\n%s",
541  iter->name, info, infostr ? infostr : "<NULL>"));
542  x_RETURN(0/*failure*/);
543  }
544  }
545  if (info->time) {
546  /* allow up to 10% of "excessive expiration" */
547  static const TNCBI_Time delta
548  = (LBSM_DEFAULT_TIME * 11 + LBSM_DEFAULT_TIME % 10) / 10;
549  if (info->time < iter->time) {
551  ("[%s] Expired entry (%u < %u) @%p:\n%s", iter->name,
552  info->time, iter->time,
553  info, infostr ? infostr : "<NULL>"));
554  x_RETURN(0/*failure*/);
555  }
556  /* for the case of n/w delay */
557  iter->time = (TNCBI_Time) time(0);
558  if (info->time > iter->time + delta) {
560  ("[%s] Excessive expiration (%u) @%p:\n%s", iter->name,
561  info->time - iter->time,
562  info, infostr ? infostr : "<NULL>"));
563  x_RETURN(0/*failure*/);
564  }
565  }
566  if (info->type == fSERV_Firewall) {
567  if (info->u.firewall.type == fSERV_Dns) {
569  ("[%s] Firewall DNS entry not allowed @%p:\n%s",
570  iter->name, info, infostr ? infostr : "<NULL>"));
571  x_RETURN(0/*failure*/);
572  }
573  if (info->vhost | info->extra) {
575  ("[%s] Firewall entry with %s%s%s @%p:\n%s", iter->name,
576  info->vhost ? "vhost" : "",
577  info->extra && info->vhost ? " and " : "",
578  info->extra ? "extra" : "",
579  info, infostr ? infostr : "<NULL>"));
580  x_RETURN(0/*failure*/);
581  }
582  }
583  if (info->type == fSERV_Dns) {
584  if (info->site & fSERV_Private) {
586  ("[%s] DNS entry cannot be private @%p:\n%s",
587  iter->name, info, infostr ? infostr : "<NULL>"));
588  x_RETURN(0/*failure*/);
589  }
590  if (info->mode & fSERV_Stateful) {
592  ("[%s] DNS entry cannot be stateful @%p:\n%s",
593  iter->name, info, infostr ? infostr : "<NULL>"));
594  x_RETURN(0/*failure*/);
595  }
596  if (info->mode & fSERV_Secure) {
598  ("[%s] DNS entry cannot be secure @%p:\n%s",
599  iter->name, info, infostr ? infostr : "<NULL>"));
600  x_RETURN(0/*failure*/);
601  }
602  if (info->mime_t != eMIME_T_Undefined ||
603  info->mime_s != eMIME_Undefined ||
604  info->mime_e != eENCOD_None) {
606  ("[%s] DNS entry with MIME type @%p:\n%s", iter->name,
607  info, infostr ? infostr : "<NULL>"));
608  x_RETURN(0/*failure*/);
609  }
610  }
611  if ((info->type & fSERV_Http) && (info->mode & fSERV_Stateful)) {
613  ("[%s] HTTP entry cannot be stateful @%p:\n%s", iter->name,
614  info, infostr ? infostr : "<NULL>"));
615  x_RETURN(0/*failure*/);
616  }
617  if (!(types = iter->types &
619  if (info->type == fSERV_Dns && !iter->reverse_dns) {
621  ("[%s] DNS entry unwarranted @%p:\n%s", iter->name,
622  info, infostr ? infostr : "<NULL>"));
623  x_RETURN(0/*failure*/);
624  }
625  } else if ((info->type != fSERV_Firewall
626  && !(types & info->type)) ||
627  (info->type == fSERV_Firewall
628  && !(types & info->u.firewall.type))) {
629  if (info->type != fSERV_Dns || !iter->reverse_dns) {
631  ("[%s] Mismatched type 0x%X vs 0x%X @%p:\n%s",
632  iter->name, (int)(info->type == fSERV_Firewall
633  ? info->u.firewall.type
634  : info->type), (int) types,
635  info, infostr ? infostr : "<NULL>"));
636  x_RETURN(0/*failure*/);
637  }
638  }
639  if (iter->external && (info->site & (fSERV_Local | fSERV_Private))) {
641  ("[%s] Local/private entry for external @%p:\n%s",
642  iter->name, info, infostr ? infostr : "<NULL>"));
643  x_RETURN(0/*failure*/);
644  }
645  if ((info->site & fSERV_Private) && !iter->ok_private
646  && iter->localhost && info->host != iter->localhost) {
648  ("[%s] Private entry unwarranted @%p:\n%s", iter->name,
649  info, infostr ? infostr : "<NULL>"));
650  x_RETURN(0/*failure*/);
651  }
652  if ((iter->types & fSERV_Stateless) && (info->mode & fSERV_Stateful)) {
654  ("[%s] Stateful entry in stateless search @%p:\n%s",
655  iter->name, info, infostr ? infostr : "<NULL>"));
656  x_RETURN(0/*failure*/);
657  }
658  if (info->type != fSERV_Dns || info->host) {
659  if (!info->time && !info->rate) {
661  ("[%s] Off entry not allowed @%p:\n%s", iter->name,
662  info, infostr ? infostr : "<NULL>"));
663  x_RETURN(0/*failure*/);
664  }
665  if (SERV_IfSuppressed(info) && !iter->ok_suppressed) {
667  ("[%s] Suppressed entry unwarranted @%p:\n%s",
668  iter->name, info, infostr ? infostr : "<NULL>"));
669  x_RETURN(0/*failure*/);
670  }
671  if (SERV_IsDown(info) && !iter->ok_down) {
673  ("[%s] Down entry unwarranted @%p:\n%s", iter->name,
674  info, infostr ? infostr : "<NULL>"));
675  x_RETURN(0/*failure*/);
676  }
677  if (SERV_IsReserved(info) && !iter->ok_reserved) {
679  ("[%s] Reserved entry unwarranted @%p:\n%s", iter->name,
680  info, infostr ? infostr : "<NULL>"));
681  x_RETURN(0/*failure*/);
682  }
683  if (SERV_IsStandby(info) && !iter->ok_standby) {
684  for (n = 0; n < iter->n_skip; ++n) {
685  if (!SERV_IsStandby(iter->skip[n])) {
687  ("[%s] Standby entry unwarranted @%p:\n%s",
688  iter->name, info, infostr? infostr : "<NULL>"));
689  x_RETURN(0/*failure*/);
690  }
691  }
692  }
693  }
694  for (n = 0; n < iter->n_skip; ++n) {
695  const SSERV_Info* skip = iter->skip[n];
696  if (strcasecmp(name, SERV_NameOfInfo(skip)) == 0
697  && SERV_EqualInfo(info, skip)) {
699  ("[%s] Entry is a duplicate of @%p and must be skipped"
700  " @%p:\n%s%s%s%s", iter->name, skip, info,
701  &"\""[!*name], name, *name ? "\" " : "",
702  infostr ? infostr : "<NULL>"));
703  x_RETURN(0/*failure*/);
704  }
705  }
706 
707  CORE_LOGF(eLOG_Trace, ("[%s] Consistency check passed @%p:\n%s%s%s%s",
708  iter->name, info, &"\""[!*name], name,
709  *name ? "\" " : "", infostr ? infostr : "<NULL>"));
710  x_RETURN(1/*success*/);
711 }
712 
713 
714 #undef x_RETURN
715 
716 #endif /*_DEBUG && !NDEBUG*/
717 
718 
720  HOST_INFO* host_info,
721  int/*bool*/ internal)
722 {
723  SSERV_Info* info = 0;
724  assert(iter && iter->op);
725  if (iter->op->GetNextInfo) {
726  if (!internal) {
727  iter->time = (TNCBI_Time) time(0);
728  s_SkipSkip(iter);
729  }
730  /* Obtain a fresh entry from the actual mapper */
731  while ((info = iter->op->GetNextInfo(iter, host_info)) != 0) {
732  int/*bool*/ go;
733  CORE_DEBUG_ARG(if (!x_ConsistencyCheck(iter, info)) return 0);
734  /* This should never be actually used for LBSMD dispatcher,
735  * as all exclusion logic is already done in it internally. */
736  go =
737  !info->host || iter->pref >= 0.0 ||
738  !iter->host || (iter->host == info->host &&
739  (!iter->port || iter->port == info->port));
740  if (go && internal)
741  break;
742  if (!s_AddSkipInfo(iter, SERV_NameOfInfo(info), info)) {
743  free(info);
744  info = 0;
745  }
746  if (go || !info)
747  break;
748  }
749  }
750  if (!internal)
751  iter->last = info;
752  return info;
753 }
754 
755 
756 static SERV_ITER s_Open(const char* service,
757  int/*bool*/ ismask,
759  unsigned int preferred_host,
760  unsigned short preferred_port,
761  double preference,
762  const SConnNetInfo* net_info,
763  SSERV_InfoCPtr skip[],
764  size_t n_skip,
765  int/*bool*/ external,
766  const char* arg,
767  const char* val,
768  SSERV_Info** info,
769  HOST_INFO* host_info)
770 {
771  SSERV_Info* x_info;
772  SERV_ITER iter = x_Open(service, ismask, types,
773  preferred_host, preferred_port, preference,
774  net_info, skip, n_skip,
775  external, arg, val,
776  &x_info, host_info);
777  assert(!iter || iter->op);
778  if (!iter)
779  x_info = 0;
780  else if (!x_info)
781  x_info = info ? s_GetNextInfo(iter, host_info, 1/*internal*/) : 0;
782  else if (x_info == (SSERV_Info*)(-1L)) {
783  SERV_Close(iter);
784  x_info = 0;
785  iter = 0;
786  }
787  if (info)
788  *info = x_info;
789  else if (x_info)
790  free(x_info);
791  return iter;
792 }
793 
794 
795 extern SERV_ITER SERV_OpenSimple(const char* service)
796 {
797  SConnNetInfo* net_info = ConnNetInfo_Create(service);
798  SERV_ITER iter = s_Open(service, 0/*not mask*/, fSERV_Any,
799  SERV_ANYHOST,
800  0/*preferred_port*/, 0.0/*preference*/,
801  net_info, 0/*skip*/, 0/*n_skip*/,
802  0/*not external*/, 0/*arg*/, 0/*val*/,
803  0/*info*/, 0/*host_info*/);
804  ConnNetInfo_Destroy(net_info);
805  return iter;
806 }
807 
808 
809 extern SERV_ITER SERV_Open(const char* service,
811  unsigned int preferred_host,
812  const SConnNetInfo* net_info)
813 {
814  return s_Open(service, 0/*not mask*/, types,
815  preferred_host, 0/*preferred_port*/, 0.0/*preference*/,
816  net_info, 0/*skip*/, 0/*n_skip*/,
817  0/*not external*/, 0/*arg*/, 0/*val*/,
818  0/*info*/, 0/*host_info*/);
819 }
820 
821 
822 extern SERV_ITER SERV_OpenEx(const char* service,
824  unsigned int preferred_host,
825  const SConnNetInfo* net_info,
826  SSERV_InfoCPtr skip[],
827  size_t n_skip)
828 {
829  return s_Open(service, 0/*not mask*/, types,
830  preferred_host, 0/*preferred_port*/, 0.0/*preference*/,
831  net_info, skip, n_skip,
832  0/*not external*/, 0/*arg*/, 0/*val*/,
833  0/*info*/, 0/*host_info*/);
834 }
835 
836 
837 SERV_ITER SERV_OpenP(const char* service,
839  unsigned int preferred_host,
840  unsigned short preferred_port,
841  double preference,
842  const SConnNetInfo* net_info,
843  SSERV_InfoCPtr skip[],
844  size_t n_skip,
845  int/*bool*/ external,
846  const char* arg,
847  const char* val)
848 {
849  return s_Open(service,
850  service && (!*service || strpbrk(service, "?*[")), types,
851  preferred_host, preferred_port, preference,
852  net_info, skip, n_skip,
853  external, arg, val,
854  0/*info*/, 0/*host_info*/);
855 }
856 
857 
858 extern SSERV_Info* SERV_GetInfoSimple(const char* service)
859 {
860  SConnNetInfo* net_info = ConnNetInfo_Create(service);
862  SERV_ANYHOST/*preferred_host*/,
863  0/*preferred_port*/, 0.0/*preference*/,
864  net_info, 0/*skip*/, 0/*n_skip*/,
865  0/*not external*/, 0/*arg*/, 0/*val*/,
866  0/*host_info*/);
867  ConnNetInfo_Destroy(net_info);
868  return info;
869 }
870 
871 
872 extern SSERV_Info* SERV_GetInfo(const char* service,
874  unsigned int preferred_host,
875  const SConnNetInfo* net_info)
876 {
877  return SERV_GetInfoP(service, types,
878  preferred_host,
879  0/*preferred_port*/, 0.0/*preference*/,
880  net_info, 0/*skip*/, 0/*n_skip*/,
881  0/*not external*/, 0/*arg*/, 0/*val*/,
882  0/*host_info*/);
883 }
884 
885 
886 extern SSERV_Info* SERV_GetInfoEx(const char* service,
888  unsigned int preferred_host,
889  const SConnNetInfo* net_info,
890  SSERV_InfoCPtr skip[],
891  size_t n_skip,
892  HOST_INFO* host_info)
893 {
894  return SERV_GetInfoP(service, types,
895  preferred_host,
896  0/*preferred_port*/, 0.0/*preference*/,
897  net_info, skip, n_skip,
898  0/*not external*/, 0/*arg*/, 0/*val*/,
899  host_info);
900 }
901 
902 
903 SSERV_Info* SERV_GetInfoP(const char* service,
905  unsigned int preferred_host,
906  unsigned short preferred_port,
907  double preference,
908  const SConnNetInfo* net_info,
909  SSERV_InfoCPtr skip[],
910  size_t n_skip,
911  int/*bool*/ external,
912  const char* arg,
913  const char* val,
914  HOST_INFO* host_info)
915 {
916  SSERV_Info* info;
917  SERV_ITER iter = s_Open(service, 0/*not mask*/, types,
918  preferred_host, preferred_port, preference,
919  net_info, skip, n_skip,
920  external, arg, val,
921  &info, host_info);
922  assert(!info || iter);
923  SERV_Close(iter);
924  return info;
925 }
926 
927 
929  HOST_INFO* host_info)
930 {
931  assert(!iter || iter->op);
932  return iter ? s_GetNextInfo(iter, host_info, 0) : 0;
933 }
934 
935 
937 {
938  assert(!iter || iter->op);
939  return iter ? s_GetNextInfo(iter, 0, 0) : 0;
940 }
941 
942 
943 const char* SERV_MapperName(SERV_ITER iter)
944 {
945  assert(!iter || iter->op);
946  return iter ? iter->op->mapper : 0;
947 }
948 
949 
950 const char* SERV_CurrentName(SERV_ITER iter)
951 {
952  const char* name = SERV_NameOfInfo(iter->last);
953  return name && *name ? name : iter->name;
954 }
955 
956 
957 int/*bool*/ SERV_PenalizeEx(SERV_ITER iter, double fine, TNCBI_Time time)
958 {
959  assert(!iter || iter->op);
960  if (!iter || !iter->op->Feedback || !iter->last)
961  return 0/*false*/;
962  return iter->op->Feedback(iter, fine, time ? time : 1/*NB: always != 0*/);
963 }
964 
965 
966 extern int/*bool*/ SERV_Penalize(SERV_ITER iter, double fine)
967 {
968  return SERV_PenalizeEx(iter, fine, 0);
969 }
970 
971 
972 extern int/*bool*/ SERV_Rerate(SERV_ITER iter, double rate)
973 {
974  assert(!iter || iter->op);
975  if (!iter || !iter->op->Feedback || !iter->last)
976  return 0/*false*/;
977  return iter->op->Feedback(iter, rate, 0/*i.e.rate*/);
978 }
979 
980 
981 extern void SERV_Reset(SERV_ITER iter)
982 {
983  if (!iter)
984  return;
985  iter->last = 0;
986  iter->time = 0;
987  s_SkipSkip(iter);
988  if (iter->op && iter->op->Reset)
989  iter->op->Reset(iter);
990 }
991 
992 
993 extern void SERV_Close(SERV_ITER iter)
994 {
995  size_t i;
996  if (!iter)
997  return;
998  SERV_Reset(iter);
999  for (i = 0; i < iter->n_skip; i++)
1000  free((void*) iter->skip[i]);
1001  iter->n_skip = 0;
1002  if (iter->op) {
1003  if (iter->op->Close)
1004  iter->op->Close(iter);
1005  iter->op = 0;
1006  }
1007  if (iter->skip)
1008  free((void*) iter->skip);
1009  free((void*) iter->name);
1010  free(iter);
1011 }
1012 
1013 
1014 int/*bool*/ SERV_Update(SERV_ITER iter, const char* text, int code)
1015 {
1016  static const char used_server_info[] = "Used-Server-Info-";
1017  int retval = 0/*not updated yet*/;
1018  const char *c, *s;
1019 
1020  iter->time = (TNCBI_Time) time(0);
1021  for (s = text; (c = strchr(s, '\n')) != 0; s = c + 1) {
1022  size_t len = (size_t)(c - s);
1023  SSERV_Info* info;
1024  unsigned int d1;
1025  char *p, *q;
1026  int d2;
1027 
1028  if (!(q = (char*) malloc(len + 1)))
1029  continue;
1030  memcpy(q, s, len);
1031  if (q[len - 1] == '\r')
1032  q[len - 1] = '\0';
1033  else
1034  q[len ] = '\0';
1035  p = q;
1036  if (iter->op->Update && iter->op->Update(iter, p, code))
1037  retval = 1/*updated*/;
1038  if (!strncasecmp(p, used_server_info, sizeof(used_server_info) - 1)
1039  && isdigit((unsigned char) p[sizeof(used_server_info) - 1])) {
1040  p += sizeof(used_server_info) - 1;
1041  if (sscanf(p, "%u: %n", &d1, &d2) >= 1
1042  && (info = SERV_ReadInfoEx(p + d2, "", 0)) != 0) {
1043  if (!s_AddSkipInfo(iter, "", info))
1044  free(info);
1045  else
1046  retval = 1/*updated*/;
1047  }
1048  }
1049  free(q);
1050  }
1051  return retval;
1052 }
1053 
1054 
1055 char* SERV_Print(SERV_ITER iter, const SConnNetInfo* net_info, int but_last)
1056 {
1057  static const char kAcceptedServerTypes[] = "Accepted-Server-Types:";
1058  static const char kClientRevision[] = "Client-Revision: %u.%u\r\n";
1059  static const char kUsedServerInfo[] = "Used-Server-Info: ";
1060  static const char kNcbiExternal[] = NCBI_EXTERNAL ": Y\r\n";
1061  static const char kNcbiFWPorts[] = "NCBI-Firewall-Ports: ";
1062  static const char kPreference[] = "Preference: ";
1063  static const char kSkipInfo[] = "Skip-Info-%u: ";
1064  static const char kAffinity[] = "Affinity: ";
1065  char buffer[128], *str;
1066  size_t buflen, i;
1067  BUF buf = 0;
1068 
1069  /* Put client version number */
1070  buflen = (size_t) sprintf(buffer, kClientRevision,
1073  assert(buflen < sizeof(buffer));
1074  if (!BUF_Write(&buf, buffer, buflen)) {
1075  BUF_Destroy(buf);
1076  return 0;
1077  }
1078  if (iter) {
1080  if (iter->external) {
1081  /* External */
1082  if (!BUF_Write(&buf, kNcbiExternal, sizeof(kNcbiExternal)-1)) {
1083  BUF_Destroy(buf);
1084  return 0;
1085  }
1086  }
1087  if ((types = (iter->types & fSERV_All)) != fSERV_Any) {
1088  /* Accepted server types */
1089  TSERV_TypeOnly t;
1090  buflen = 0;
1091  for (t = 1; t; t <<= 1) {
1092  if (types & t) {
1093  const char* name = SERV_TypeStr((ESERV_Type) t);
1094  size_t namelen = strlen(name);
1095  if (!namelen)
1096  continue;
1097  if (buflen + namelen + (1 + 2) > sizeof(buffer))
1098  break;
1099  buffer[buflen++] = ' ';
1100  memcpy(buffer + buflen, name, namelen);
1101  buflen += namelen;
1102  } else if (types < t)
1103  break;
1104  }
1105  if (buflen) {
1106  memcpy(buffer + buflen, "\r\n", 2);
1107  if (!BUF_Write(&buf, kAcceptedServerTypes,
1108  sizeof(kAcceptedServerTypes) - 1)
1109  || !BUF_Write(&buf, buffer, buflen + 2)) {
1110  BUF_Destroy(buf);
1111  return 0;
1112  }
1113  }
1114  }
1115  if (types & fSERV_Firewall) {
1116  /* Firewall */
1117  EFWMode mode
1118  = net_info ? (EFWMode) net_info->firewall : eFWMode_Legacy;
1120  if (*buffer
1121  && (!BUF_Write(&buf, kNcbiFWPorts, sizeof(kNcbiFWPorts)-1) ||
1122  !BUF_Write(&buf, buffer, strlen(buffer)) ||
1123  !BUF_Write(&buf, "\r\n", 2))) {
1124  BUF_Destroy(buf);
1125  return 0;
1126  }
1127  }
1128  if (iter->pref && (iter->host | iter->port)) {
1129  /* Preference */
1130  buflen = SOCK_HostPortToString(iter->host, iter->port,
1131  buffer, sizeof(buffer));
1132  buffer[buflen++] = ' ';
1133  buflen = (size_t)(strcpy(NCBI_simple_ftoa(buffer + buflen,
1134  iter->pref * 100.0, 2),
1135  "%\r\n") - buffer) + 3/*"%\r\n"*/;
1136  if (!BUF_Write(&buf, kPreference, sizeof(kPreference) - 1) ||
1137  !BUF_Write(&buf, buffer, buflen)) {
1138  BUF_Destroy(buf);
1139  return 0;
1140  }
1141  }
1142  if (iter->arglen) {
1143  /* Affinity */
1144  if (!BUF_Write(&buf, kAffinity, sizeof(kAffinity) - 1) ||
1145  !BUF_Write(&buf, iter->arg, iter->arglen) ||
1146  (iter->val && (!BUF_Write(&buf, "=", 1) ||
1147  !BUF_Write(&buf, iter->val, iter->vallen))) ||
1148  !BUF_Write(&buf, "\r\n", 2)) {
1149  BUF_Destroy(buf);
1150  return 0;
1151  }
1152  }
1153  /* Drop any outdated skip entries */
1154  iter->time = (TNCBI_Time) time(0);
1155  s_SkipSkip(iter);
1156  /* Put all the rest into rejection list */
1157  for (i = 0; i < iter->n_skip; ++i) {
1158  /* NB: all skip infos are now kept with names (perhaps, empty) */
1159  const char* name = SERV_NameOfInfo(iter->skip[i]);
1160  size_t namelen = name && *name ? strlen(name) : 0;
1161  if (!(str = SERV_WriteInfo(iter->skip[i])))
1162  break;
1163  if (but_last && iter->last == iter->skip[i]) {
1164  buflen = sizeof(kUsedServerInfo) - 1;
1165  memcpy(buffer, kUsedServerInfo, buflen);
1166  } else
1167  buflen = (size_t) sprintf(buffer, kSkipInfo, (unsigned) i + 1);
1168  assert(buflen < sizeof(buffer) - 1);
1169  if (!BUF_Write(&buf, buffer, buflen) ||
1170  (namelen && !BUF_Write(&buf, name, namelen)) ||
1171  (namelen && !BUF_Write(&buf, " ", 1)) ||
1172  !BUF_Write(&buf, str, strlen(str)) ||
1173  !BUF_Write(&buf, "\r\n", 2)) {
1174  free(str);
1175  break;
1176  }
1177  free(str);
1178  }
1179  if (i < iter->n_skip) {
1180  BUF_Destroy(buf);
1181  return 0;
1182  }
1183  }
1184  /* Ok then, we have filled the entire header, <CR><LF> terminated */
1185  if ((buflen = BUF_Size(buf)) != 0) {
1186  if ((str = (char*) malloc(buflen + 1)) != 0) {
1187  if (BUF_Read(buf, str, buflen) != buflen) {
1188  free(str);
1189  str = 0;
1190  } else
1191  str[buflen] = '\0';
1192  }
1193  } else
1194  str = 0;
1195  BUF_Destroy(buf);
1196  return str;
1197 }
1198 
1199 
1200 extern unsigned short SERV_ServerPort(const char* name,
1201  unsigned int host)
1202 {
1203  SSERV_Info* info;
1204  unsigned short port;
1205 
1206  /* FIXME: SERV_LOCALHOST may not need to be resolved here,
1207  * but taken from LBSMD table (or resolved later in DISPD/LOCAL
1208  * if needed).
1209  */
1210  if (!host || host == SERV_LOCALHOST)
1213  host, 0/*pref. port*/, -1.0/*latch host*/,
1214  0/*net_info*/, 0/*skip*/, 0/*n_skip*/,
1215  0/*not external*/, 0/*arg*/, 0/*val*/,
1216  0/*host_info*/))) {
1217  return 0;
1218  }
1219  assert(info->host == host);
1220  port = info->port;
1221  free((void*) info);
1222  assert(port);
1223  return port;
1224 }
1225 
1226 
1227 extern int/*bool*/ SERV_SetImplicitServerType(const char* service,
1228  ESERV_Type type)
1229 {
1230  char* buf, *svc = SERV_ServiceName(service);
1231  const char* typ = SERV_TypeStr(type);
1232  size_t len;
1233 
1234  if (!svc)
1235  return 0/*failure*/;
1236  /* Store service-specific setting */
1238  free(svc);
1239  return 1/*success*/;
1240  }
1241  len = strlen(svc);
1242  if (!(buf = (char*) realloc(svc, len + sizeof(CONN_IMPLICIT_SERVER_TYPE)
1243  + 2/*"=\0"*/) + strlen(typ))) {
1244  free(svc);
1245  return 0/*failure*/;
1246  }
1247  x_tr(strupr(buf), '-', '_', len);
1248  memcpy(buf + len,
1250  sizeof(CONN_IMPLICIT_SERVER_TYPE));
1251  len += sizeof(CONN_IMPLICIT_SERVER_TYPE);
1252 #ifdef HAVE_SETENV
1253  buf[len++] = '\0';
1254 #else
1255  buf[len++] = '=';
1256 #endif /*HAVE_SETENV*/
1257  strcpy(buf + len, typ);
1258 
1260 #ifdef HAVE_SETENV
1261  len = !setenv(buf, buf + len, 1/*overwrite*/);
1262 #else
1263  /* NOTE that putenv() leaks memory if the environment is later replaced */
1264 # ifdef NCBI_OS_MSWIN
1265 # define putenv _putenv
1266 # endif /*NCBI_OS_MSWIN*/
1267  len = !putenv(buf);
1268 #endif /*HAVE_SETENV*/
1269  CORE_UNLOCK;
1270 
1271 #ifndef HAVE_SETENV
1272  if (!len)
1273 #endif /*!HAVE_SETENV*/
1274  free(buf);
1275  return len ? 1/*success*/ : 0/*failure*/;
1276 }
1277 
1278 
1279 #define SERV_MERGE(a, b) a ## b
1280 
1281 #define SERV_GET_IMPLICIT_SERVER_TYPE(variant) \
1282  ESERV_Type SERV_MERGE(SERV_GetImplicitServerType, variant) \
1283  (const char* service) \
1284  { \
1285  ESERV_Type type; \
1286  const char *end; \
1287  char val[40]; \
1288  /* Try to retrieve service-specific first, then global default */ \
1289  if (!SERV_MERGE(ConnNetInfo_GetValue, variant) \
1290  (service, REG_CONN_IMPLICIT_SERVER_TYPE, val, sizeof(val), 0) \
1291  || !*val || !(end = SERV_ReadType(val, &type)) || *end) { \
1292  return SERV_GetImplicitServerTypeDefault(); \
1293  } \
1294  return type; \
1295  } \
1296 
1297 
1298 /* Public API */
1299 #define SERV_GET_IMPLICIT_SERVER_TYPE_PUBLIC_API
1301 #undef SERV_GET_IMPLICIT_SERVER_TYPE_PUBLIC_API
1302 
1303 
1304 /* Internal API */
1306 
1307 
1308 #undef SERV_GET_IMPLICIT_SERVER_TYPE
1309 
1310 #undef SERV_MERGE
1311 
1312 
1314 {
1315  return fSERV_Http;
1316 }
1317 
1318 
1319 #if 0
1320 int/*bool*/ SERV_MatchesHost(const SSERV_Info* info, unsigned int host)
1321 {
1322  if (host == SERV_ANYHOST)
1323  return 1/*true*/;
1324  if (host != SERV_LOCALHOST)
1325  return info->host == host ? 1/*true*/ : 0/*false*/;
1326  if (!info->host || info->host == SOCK_GetLocalHostAddress(eDefault))
1327  return 1/*true*/;
1328  return 0/*false*/;
1329 }
1330 #endif
1331 
1332 
1334 {
1335  ESwitch retval = s_Fast;
1336  if (on != eDefault)
1337  s_Fast = on;
1338  return retval;
1339 }
static CBioSource dummy
static unsigned char depth[2 *(256+1+29)+1]
#define setenv
Definition: common.h:195
@ eOff
Definition: ncbi_types.h:110
@ eDefault
Definition: ncbi_types.h:112
int BUF_Write(BUF *pBuf, const void *data, size_t size)
Definition: ncbi_buffer.c:224
size_t BUF_Size(BUF buf)
Definition: ncbi_buffer.c:84
size_t BUF_Read(BUF buf, void *data, size_t size)
Definition: ncbi_buffer.c:414
void BUF_Destroy(BUF buf)
Definition: ncbi_buffer.c:500
ESERV_Type
SSERV_InfoCPtr SERV_GetNextInfo(SERV_ITER iter)
Same as "SERV_GetNextInfoEx(., 0)" – i.e.
Definition: ncbi_service.c:936
TNCBI_Time time
void SERV_Close(SERV_ITER iter)
Deallocate the iterator.
Definition: ncbi_service.c:993
SSERV_Info * SERV_GetInfoEx(const char *service, TSERV_Type types, unsigned int preferred_host, const SConnNetInfo *net_info, SSERV_InfoCPtr skip[], size_t n_skip, HOST_INFO *host_info)
A "fast track" routine equivalent to creating of an iterator as with SERV_OpenEx(),...
Definition: ncbi_service.c:886
#define SERV_ANYHOST
Definition: ncbi_service.h:55
SSERV_Info * SERV_GetInfoSimple(const char *service)
Equivalent to "SERV_GetInfo(., fSERV_Any, SERV_ANYHOST, ConnNetInfo_Crea...
Definition: ncbi_service.c:858
int SERV_SetImplicitServerType(const char *service, ESERV_Type type)
Set a server type to use when a service mapper returns typeless entries for the given service name (t...
SSERV_FirewallInfo firewall
void SERV_Reset(SERV_ITER iter)
Reset the iterator to the state as if it has just been opened.
Definition: ncbi_service.c:981
int SERV_Penalize(SERV_ITER iter, double fine)
Penalize the server returned last from SERV_GetNextInfo[Ex]().
Definition: ncbi_service.c:966
unsigned short SERV_ServerPort(const char *name, unsigned int host)
Obtain a port number that corresponds to the named (standalone) service declared at the specified hos...
const char * SERV_TypeStr(ESERV_Type type)
SSERV_Info * SERV_GetInfo(const char *service, TSERV_Type types, unsigned int preferred_host, const SConnNetInfo *net_info)
Same as "SERV_GetInfoEx(., ., ., ., 0, 0, 0)" – i.e.
Definition: ncbi_service.c:872
SERV_ITER SERV_OpenEx(const char *service, TSERV_Type types, unsigned int preferred_host, const SConnNetInfo *net_info, SSERV_InfoCPtr skip[], size_t n_skip)
Create an iterator for sequential server lookup.
Definition: ncbi_service.c:822
SERV_ITER SERV_Open(const char *service, TSERV_Type types, unsigned int preferred_host, const SConnNetInfo *net_info)
Same as "SERV_OpenEx(., ., ., ., 0, 0)" – i.e.
Definition: ncbi_service.c:809
char * SERV_WriteInfo(const SSERV_Info *info)
unsigned int TSERV_Type
Bitwise OR of ESERV_Type[Special].
Definition: ncbi_service.h:94
unsigned short TSERV_TypeOnly
Server type only, w/o specials.
Definition: ncbi_service.h:95
unsigned int host
int SERV_Rerate(SERV_ITER iter, double rate)
Rerate the server returned last from SERV_GetNextInfo[Ex]().
Definition: ncbi_service.c:972
SERV_ITER SERV_OpenSimple(const char *service)
Allocate an iterator and consult either local databases (if any present), or network database,...
Definition: ncbi_service.c:795
#define SERV_CLIENT_REVISION_MAJOR
Revision 7.0.
Definition: ncbi_service.h:47
USERV_Info u
#define SERV_CLIENT_REVISION_MINOR
Definition: ncbi_service.h:48
#define SERV_LOCALHOST
Special values for the "preferred_host" parameter.
Definition: ncbi_service.h:54
int SERV_EqualInfo(const SSERV_Info *info1, const SSERV_Info *info2)
ESERV_Type type
SSERV_InfoCPtr SERV_GetNextInfoEx(SERV_ITER iter, HOST_INFO *host_info)
Get the next server meta-address, optionally accompanied by the host parameters made available by the...
Definition: ncbi_service.c:928
@ fSERV_Firewall
@ fSERV_Http
@ fSERV_Standalone
@ fSERV_Dns
@ fSERV_ReverseDns
LB-DNS translation.
Definition: ncbi_service.h:84
@ fSERV_IncludeSuppressed
Definition: ncbi_service.h:89
@ fSERV_All
Server type mask.
Definition: ncbi_service.h:80
@ fSERV_Stateless
Stateless servers only.
Definition: ncbi_service.h:81
@ fSERV_IncludeStandby
Definition: ncbi_service.h:87
@ fSERV_IncludeDown
Definition: ncbi_service.h:86
@ fSERV_Any
Definition: ncbi_service.h:79
@ fSERV_Promiscuous
Evrthng and the kitchen sink.
Definition: ncbi_service.h:92
@ fSERV_IncludeReserved
Definition: ncbi_service.h:88
@ fSERV_IncludePrivate
Definition: ncbi_service.h:91
@ fSERV_Secure
@ fSERV_Stateful
@ fSERV_Local
@ fSERV_Private
size_t SOCK_HostPortToString(unsigned int host, unsigned short port, char *buf, size_t bufsize)
Print numeric string "host:port" into a buffer provided, not to exceed 'bufsize' bytes (including the...
Definition: ncbi_socket.c:8949
unsigned int SOCK_GetLocalHostAddress(ESwitch reget)
Get (and cache for faster follow-up retrievals) IPv4 address of local host.
Definition: ncbi_socket.c:8831
#define REG_CONN_LBSMD_DISABLE
unsigned external
unsigned lb_disable
EBFWMode firewall
enum ENcbiSwitch ESwitch
Aux.
unsigned int TNCBI_Time
Definition: ncbi_types.h:145
#define REG_CONN_LINKERD_ENABLE
#define REG_CONN_LBDNS_ENABLE
#define REG_CONN_LOCAL_ENABLE
unsigned stateless
#define NCBI_TIME_INFINITE
Definition: ncbi_types.h:147
EFWMode
#define REG_CONN_NAMERD_ENABLE
#define REG_CONN_DISPD_DISABLE
SConnNetInfo * ConnNetInfo_Create(const char *service)
int ConnNetInfo_Boolean(const char *str)
#define REG_CONN_SERVICE_NAME
void ConnNetInfo_Destroy(SConnNetInfo *net_info)
@ eLOG_Critical
Definition: ncbi_core.h:298
@ eLOG_Error
Definition: ncbi_core.h:297
@ eLOG_Trace
Definition: ncbi_core.h:293
@ eMIME_T_Undefined
@ eREG_Transient
only in-memory storage while program runs
Definition: ncbi_core.h:529
@ eMIME_Undefined
@ eENCOD_None
@ eFWMode_Legacy
Relay, no firewall.
char * buf
int i
yy_size_t n
int len
static void text(MDB_val *v)
Definition: mdb_dump.c:62
static MDB_envinfo info
Definition: mdb_load.c:37
mdb_mode_t mode
Definition: lmdb++.h:38
const struct ncbi::grid::netcache::search::fields::KEY key
int NCBI_HasSpaces(const char *s, size_t n)
Return non-zero(true) if a block of memory based at "s" and of size "n" has any space characters (as ...
char * NCBI_simple_ftoa(char *s, double f, int p)
Locale-independent double-to-ASCII conversion of value "f" into a character buffer pointed to by "s",...
#define strdup
Definition: ncbi_ansi_ext.h:70
#define strncasecmp
#define strcasecmp
#define strupr
#define NCBI_EXTERNAL
Definition: ncbi_comm.h:57
#define LBSM_DEFAULT_TIME
Definition: ncbi_comm.h:45
const char * ConnNetInfo_GetValueInternal(const char *service, const char *param, char *value, size_t value_size, const char *def_value)
void SERV_PrintFirewallPorts(char *buf, size_t bufsize, EFWMode mode)
const SSERV_VTable * SERV_DISPD_Open(SERV_ITER iter, const SConnNetInfo *net_info, SSERV_Info **info)
Definition: ncbi_dispd.c:397
const SSERV_VTable * SERV_LBDNS_Open(SERV_ITER iter, SSERV_Info **info)
Definition: ncbi_lbdns.c:1505
const SSERV_VTable * SERV_LBSMD_Open(SERV_ITER iter, SSERV_Info **info, HOST_INFO *host_info, int no_dispd_follows)
Definition: ncbi_lbsmd.c:1072
const SSERV_VTable * SERV_LINKERD_Open(SERV_ITER iter, const SConnNetInfo *net_info, SSERV_Info **info, int *do_namerd)
Definition: ncbi_linkerd.c:525
const SSERV_VTable * SERV_LOCAL_Open(SERV_ITER iter, SSERV_Info **info)
Definition: ncbi_local.c:374
unsigned int a
Definition: ncbi_localip.c:102
EIPRangeType t
Definition: ncbi_localip.c:101
const SSERV_VTable * SERV_NAMERD_Open(SERV_ITER iter, const SConnNetInfo *net_info, SSERV_Info **info)
Definition: ncbi_namerd.c:1486
#define CORE_REG_GET(section, name, value, value_size, def_value)
Definition: ncbi_priv.h:297
#define CORE_DEBUG_ARG(arg)
Definition: ncbi_priv.h:139
#define CORE_REG_SET(section, name, value, storage)
Definition: ncbi_priv.h:300
#define CORE_LOGF_X(subcode, level, fmt_args)
Definition: ncbi_priv.h:150
#define CORE_LOCK_WRITE
Definition: ncbi_priv.h:269
#define CORE_TRACEF(fmt_args)
Definition: ncbi_priv.h:138
#define CORE_UNLOCK
Definition: ncbi_priv.h:273
#define CORE_LOGF(level, fmt_args)
Definition: ncbi_priv.h:158
#define CORE_LOCK_READ
Definition: ncbi_priv.h:271
SSERV_Info * SERV_ReadInfoEx(const char *str, const char *name, int lazy)
SSERV_Info * SERV_CopyInfoEx(const SSERV_Info *orig, const char *name)
const char * SERV_NameOfInfo(const SSERV_Info *info)
static SERV_ITER s_Open(const char *service, int ismask, TSERV_Type types, unsigned int preferred_host, unsigned short preferred_port, double preference, const SConnNetInfo *net_info, SSERV_InfoCPtr skip[], size_t n_skip, int external, const char *arg, const char *val, SSERV_Info **info, HOST_INFO *host_info)
Definition: ncbi_service.c:756
#define CONN_IMPLICIT_SERVER_TYPE
Definition: ncbi_service.c:64
static void s_SkipSkip(SERV_ITER iter)
Definition: ncbi_service.c:463
static int s_AddSkipInfo(SERV_ITER iter, const char *name, SSERV_InfoCPtr info)
Definition: ncbi_service.c:193
#define SERV_GET_IMPLICIT_SERVER_TYPE(variant)
#define SERV_GET_IMPLICIT_SERVER_TYPE_PUBLIC_API
int SERV_IsMapperConfiguredInternal(const char *svc, const char *key)
Definition: ncbi_service.c:247
#define SERV_SERVICE_NAME_RECURSION_MAX
Definition: ncbi_service.c:63
static ESwitch s_Fast
Definition: ncbi_service.c:67
SSERV_Info * SERV_GetInfoP(const char *service, TSERV_Type types, unsigned int preferred_host, unsigned short preferred_port, double preference, const SConnNetInfo *net_info, SSERV_InfoCPtr skip[], size_t n_skip, int external, const char *arg, const char *val, HOST_INFO *host_info)
Definition: ncbi_service.c:903
char * SERV_ServiceName(const char *service)
Definition: ncbi_service.c:186
static SERV_ITER x_Open(const char *service, int ismask, TSERV_Type types, unsigned int preferred_host, unsigned short preferred_port, double preference, const SConnNetInfo *net_info, SSERV_InfoCPtr skip[], size_t n_skip, int external, const char *arg, const char *val, SSERV_Info **info, HOST_INFO *host_info)
Definition: ncbi_service.c:253
int SERV_Update(SERV_ITER iter, const char *text, int code)
const char * SERV_CurrentName(SERV_ITER iter)
Definition: ncbi_service.c:950
#define putenv
static int x_tr(char *str, char a, char b, size_t len)
Definition: ncbi_service.c:83
int SERV_PenalizeEx(SERV_ITER iter, double fine, TNCBI_Time time)
Definition: ncbi_service.c:957
#define s_IsMapperConfigured(s, k)
Definition: ncbi_service.c:244
#define x_getenv
Definition: ncbi_service.c:79
static int x_Return(SSERV_Info *info, const char *infostr, int retval)
Definition: ncbi_service.c:495
static int x_IsMapperConfigured(const char *svc, const char *key, int fast)
Definition: ncbi_service.c:232
static char * s_ServiceName(const char *service, int ismask, int *isfast)
Definition: ncbi_service.c:175
static SSERV_Info * s_GetNextInfo(SERV_ITER iter, HOST_INFO *host_info, int internal)
Definition: ncbi_service.c:719
ESERV_Type SERV_GetImplicitServerTypeDefault(void)
char * SERV_Print(SERV_ITER iter, const SConnNetInfo *net_info, int but_last)
ESwitch SERV_DoFastOpens(ESwitch on)
SERV_ITER SERV_OpenP(const char *service, TSERV_Type types, unsigned int preferred_host, unsigned short preferred_port, double preference, const SConnNetInfo *net_info, SSERV_InfoCPtr skip[], size_t n_skip, int external, const char *arg, const char *val)
Definition: ncbi_service.c:837
static int x_ConsistencyCheck(SERV_ITER iter, const SSERV_Info *info)
Definition: ncbi_service.c:509
static char * x_ServiceName(unsigned int depth, const char *service, const char *svc, int ismask, int *isfast)
Definition: ncbi_service.c:106
const char * SERV_MapperName(SERV_ITER iter)
Definition: ncbi_service.c:943
#define x_RETURN(retval)
Definition: ncbi_service.c:489
#define SERV_IsReserved(i)
Definition: ncbi_servicep.h:62
#define SERV_IsDown(i)
Definition: ncbi_servicep.h:63
#define SERV_IfSuppressed(i)
Definition: ncbi_servicep.h:58
#define SERV_IsStandby(i)
Definition: ncbi_servicep.h:61
#define NCBI_CXX_TOOLKIT
Definition: ncbiconf_msvc.h:16
#define NCBI_OS_UNIX
int isdigit(Uchar c)
Definition: ncbictype.hpp:64
Int4 delta(size_t dimension_, const Int4 *score_)
static char tmp[2048]
Definition: utf8.c:42
#define memmove(a, b, c)
static pcre_uint8 * buffer
Definition: pcretest.c:1051
#define assert(x)
Definition: srv_diag.hpp:58
static const char * str(char *buf, int n)
Definition: stats.c:84
unsigned ok_suppressed
Definition: ncbi_servicep.h:99
unsigned external
unsigned ok_down
Definition: ncbi_servicep.h:96
unsigned ok_reserved
Definition: ncbi_servicep.h:98
unsigned short port
Definition: ncbi_servicep.h:93
const char * arg
const char * name
Definition: ncbi_servicep.h:89
unsigned exact
SSERV_InfoCPtr * skip
unsigned ismask
Definition: ncbi_servicep.h:95
unsigned int localhost
const char * val
const SSERV_VTable * op
unsigned int host
Definition: ncbi_servicep.h:92
unsigned ok_standby
Definition: ncbi_servicep.h:97
SSERV_InfoCPtr last
unsigned ok_private
unsigned reverse_dns
TSERV_TypeOnly types
Definition: ncbi_servicep.h:94
TNCBI_Time time
Definition: ncbi_servicep.h:91
void(* Reset)(SERV_ITER iter)
Definition: ncbi_servicep.h:80
SSERV_Info *(* GetNextInfo)(SERV_ITER iter, HOST_INFO *host_info)
Definition: ncbi_servicep.h:77
const char * mapper
Definition: ncbi_servicep.h:82
void(* Close)(SERV_ITER iter)
Definition: ncbi_servicep.h:81
int(* Update)(SERV_ITER iter, const char *text, int code)
Definition: ncbi_servicep.h:79
int(* Feedback)(SERV_ITER iter, double rate, TNCBI_Time fine)
Definition: ncbi_servicep.h:78
Definition: inftrees.h:24
Definition: type.c:6
done
Definition: token1.c:1
static HENV env
Definition: transaction2.c:38
static const struct type types[]
Definition: type.c:22
void free(voidpf ptr)
voidp malloc(uInt size)
voidp calloc(uInt items, uInt size)
Modified on Wed Nov 29 02:24:09 2023 by modify_doxy.py rev. 669887