1
/* $RCSfile: ni_service.c,v $ $Revision: 6.19 $ $Date: 2004/07/12 16:34:05 $
2
* ==========================================================================
5
* National Center for Biotechnology Information
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.
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
22
* Please cite the author in any work or product based on this material.
24
* ==========================================================================
26
* Author: Anton Lavrentiev
29
* NCBI Named Service Client (based on SERVICE connector)
31
* --------------------------------------------------------------------------
32
* $Log: ni_service.c,v $
33
* Revision 6.19 2004/07/12 16:34:05 lavr
34
* Add "SRV_CONN_MODE" for alternate FIREWALL switching
35
* (Thanks to Svetlana Karamycheva for reporting this..)
37
* Revision 6.18 2004/02/23 17:00:39 lavr
38
* Fix n_written variable name typo
40
* Revision 6.17 2004/02/23 15:30:21 lavr
41
* New (last) parameter "how" added in CONN_Write() API call
43
* Revision 6.16 2003/10/27 14:10:49 lavr
44
* Better flow control in s_AsnWrite()
46
* Revision 6.15 2003/10/16 15:12:38 lavr
47
* Better flow control in s_AsnWrite()
49
* Revision 6.14 2003/10/10 19:23:58 lavr
50
* Perform persistent ASN.1 write to connection in a tight loop
51
* (work around bug in AsnIoWriteBlock that otherwise generates err 79)
53
* Revision 6.13 2002/11/26 17:00:11 lavr
54
* Recognize "SOME" and "DATA" as keyword values of "SRV_DEBUG_PRINTOUT"
56
* Revision 6.12 2002/10/04 15:33:42 lavr
57
* Few cosmetic changes
59
* Revision 6.11 2002/08/16 20:36:19 lavr
60
* Do not override net params which are not defined by old env.interface
62
* Revision 6.10 2002/08/08 02:45:28 lavr
65
* Revision 6.9 2002/08/07 18:45:21 lavr
66
* Change from deprecated to current EIO_ReadMethod enums
68
* Revision 6.8 2002/08/06 20:36:22 lavr
69
* Uppercase environment variable name to look for an alternate service name
71
* Revision 6.7 2002/05/06 19:24:38 lavr
72
* Translate service name AFTER creation of SConnNetInfo
74
* Revision 6.6 2002/04/23 17:57:54 lavr
75
* Recognize "INFINITE" as a timeout from registry/environment
77
* Revision 6.5 2002/04/16 21:58:06 lavr
78
* Few fixes after test compilation and run
80
* Revision 6.4 2002/04/16 21:33:24 lavr
81
* Add compatibility for service parameters taken as for WWW disp
83
* Revision 6.3 2002/03/23 04:21:04 lavr
86
* Revision 6.2 2002/03/22 22:22:45 lavr
87
* Try to do the best in setting up proper timeouts
89
* Revision 6.1 2001/02/21 22:09:15 lavr
92
* ==========================================================================
97
#include <connect/ncbi_connection.h>
98
#include <connect/ncbi_service_connector.h>
101
/*********************************
105
/* Hard-coded constants, environment parameter names & defaults
106
* NOTE:: These are taken from ni_www.c for backward compatibility.
107
* Their use will eventually get deprecated in the future...
110
#define SRV_SECTION "NET_SERV"
112
#define ENV_CONN_MODE "SRV_CONN_MODE"
113
#define ENV_ENGINE_HOST "SRV_ENGINE_HOST"
114
#define ENV_ENGINE_PORT "SRV_ENGINE_PORT"
115
#define ENV_ENGINE_URL "SRV_ENGINE_URL"
116
#define ENV_TIMEOUT "SRV_CONN_TIMEOUT"
117
#define ENV_CONN_TRY "SRV_CONN_TRY"
118
#define ENV_HTTP_PROXY_HOST "SRV_HTTP_PROXY_HOST"
119
#define ENV_HTTP_PROXY_PORT "SRV_HTTP_PROXY_PORT"
120
#define ENV_PROXY_HOST "SRV_PROXY_HOST"
121
#define ENV_DEBUG_PRINTOUT "SRV_DEBUG_PRINTOUT"
122
#define ENV_NO_LB_DIRECT "SRV_NO_LB_DIRECT"
128
static Int2 LIBCALLBACK s_AsnRead(Pointer p, CharPtr buf, Uint2 len)
131
CONN_Read((CONN) p, buf, len, &n_read, eIO_ReadPlain);
132
return (Int2) n_read;
136
static Int2 LIBCALLBACK s_AsnWrite(Pointer p, CharPtr buf, Uint2 len)
139
CONN_Write((CONN) p, buf, len, &n_written, eIO_WritePersist);
140
return (Int2) n_written;
144
static void LIBCALLBACK s_AsnErrorFunc(Int2 type, CharPtr message)
146
ErrPostEx(SEV_ERROR, 88, type, message);
150
/* The interface implementaion functions
153
static NI_DispatcherPtr s_GenericInit
154
(CharPtr configFile, CharPtr configSection, Boolean showMonitor,
155
CharPtr lastDispatcher, Int2 lastDispLen)
157
NI_DispatcherPtr disp = (NI_DispatcherPtr)MemNew(sizeof(NI_Dispatcher));
158
disp->interface = eNII_Service;
160
if ( lastDispatcher )
161
StringNCpy_0(lastDispatcher, "NCBI Named Service", lastDispLen);
163
disp->motd = StringSave("Load-Balanced Service Mapping Facility");
164
disp->adminInfo = StringSave("Anton Lavrentiev <lavr@ncbi.nlm.nih.gov>");
165
disp->referenceCount = 1;
170
static NI_DispatcherPtr s_SetDispatcher
171
(NI_DispatcherPtr disp, CharPtr host, CharPtr svc, int timeout,
172
Int4 dispserialnum, ValNodePtr encryption, Boolean useOutServ)
174
return s_GenericInit(0, 0, 0, 0, 0);
178
static NI_HandPtr s_GenericGetService
179
(NI_DispatcherPtr disp, CharPtr configFile, CharPtr configSection,
180
CharPtr defService, Boolean hasResource)
182
SConnNetInfo *net_info, *def_info;
190
if (!(net_info = ConnNetInfo_Create(defService))) {
191
ErrPostEx(SEV_ERROR, 0, 1, "[Service NI Client] "
192
" Cannot set parameters for service \"%s\"", defService);
195
if (!(def_info = ConnNetInfo_Clone(net_info))) {
196
ErrPostEx(SEV_ERROR, 0, 1, "[Service NI Client] "
197
" Cannot create reserve copy of network info");
198
ConnNetInfo_Destroy(net_info);
201
/* Now override default parameters with legacy parameters
202
* of older WWW service dispatcher -- should go obsolete soon... */
204
/* alternate firewall mode request */
205
NI_GetEnvParam(configFile, SRV_SECTION, ENV_CONN_MODE,
206
str, sizeof(str), "");
207
if (*str && StringICmp(str, "FIREWALL") == 0)
208
net_info->firewall = 1/*true*/;
210
/* alternate dispatcher's host name & port */
211
NI_GetEnvParam(configFile, SRV_SECTION, ENV_ENGINE_HOST,
212
net_info->host, sizeof(net_info->host), def_info->host);
214
NI_GetEnvParam(configFile, SRV_SECTION, ENV_ENGINE_PORT,
215
str, sizeof(str), "");
216
if ((val = atoi(str)) != 0)
217
net_info->port = val;
219
/* alternate the dispatcher's CGI path */
220
NI_GetEnvParam(configFile, SRV_SECTION, ENV_ENGINE_URL,
221
net_info->path, sizeof(net_info->path), def_info->path);
223
/* alternate HTTP proxy host & port */
224
NI_GetEnvParam(configFile, SRV_SECTION, ENV_HTTP_PROXY_HOST,
225
net_info->http_proxy_host,
226
sizeof(net_info->http_proxy_host),
227
def_info->http_proxy_host);
228
NI_GetEnvParam(configFile, SRV_SECTION, ENV_HTTP_PROXY_PORT,
229
str, sizeof(str), "");
230
if ((val = atoi(str)) != 0)
231
net_info->http_proxy_port = val;
233
/* alternate non-transparent CERN-like firewall proxy server */
234
NI_GetEnvParam(configFile, SRV_SECTION, ENV_PROXY_HOST,
235
net_info->proxy_host, sizeof(net_info->proxy_host),
236
def_info->proxy_host);
238
/* alternate connection timeout */
239
NI_GetEnvParam(configFile, SRV_SECTION, ENV_TIMEOUT,
240
str, sizeof(str), "");
242
if (strlen(str) > 2 && StringNICmp(str, "infinite", strlen(str)) == 0){
243
net_info->timeout = 0;
245
if (!net_info->timeout)
246
net_info->timeout = &net_info->tmo;
249
valf = DEF_CONN_TIMEOUT;
250
net_info->timeout->sec = (unsigned int) valf;
251
net_info->timeout->usec = (unsigned int)
252
((valf - net_info->timeout->sec) * 1000000);
256
/* alternate max. number of attempts to establish connection */
257
NI_GetEnvParam(configFile, SRV_SECTION, ENV_CONN_TRY,
258
str, sizeof(str), "");
259
if ((val = atoi(str)) != 0)
260
net_info->max_try = val;
262
/* alternate debug printout request */
263
NI_GetEnvParam(configFile, SRV_SECTION, ENV_DEBUG_PRINTOUT,
264
str, sizeof(str), "");
265
if (*str && (StringICmp(str, "1" ) == 0 ||
266
StringICmp(str, "true") == 0 ||
267
StringICmp(str, "yes" ) == 0 ||
268
StringICmp(str, "some") == 0))
269
net_info->debug_printout = eDebugPrintout_Some;
270
if (*str && StringICmp(str, "data") == 0)
271
net_info->debug_printout = eDebugPrintout_Data;
273
/* whether to prohibit the use of local LBSMD */
274
NI_GetEnvParam(configFile, SRV_SECTION, ENV_NO_LB_DIRECT,
275
str, sizeof(str), "");
276
if (*str && (StringICmp(str, "0" ) != 0 &&
277
StringICmp(str, "false") != 0 &&
278
StringICmp(str, "no" ) != 0))
279
net_info->lb_disable = 1/*true*/;
281
{{ /* alternate service name */
282
static const Char ENV_PREFIX[] = "NI_SERVICE_NAME_";
283
CharPtr envName = (CharPtr)MemNew(sizeof(ENV_PREFIX) +
284
StringLen(configSection));
285
StringCpy(envName, ENV_PREFIX);
286
StringCat(envName, configSection);
287
StringUpper(envName);
288
NI_GetEnvParamEx(configFile, configSection, envName, "SERVICE_NAME",
289
str, sizeof(str), defService);
293
ConnNetInfo_Destroy(def_info);
295
/* establish connection to the server */
296
if (!(c = SERVICE_CreateConnectorEx(str, fSERV_Any, net_info, 0)) ||
297
CONN_Create(c, &conn) != eIO_Success) {
298
ErrPostEx(SEV_ERROR, 0, 1, "[Service NI Client] "
299
" Service \"%s\" unusable", str);
300
ConnNetInfo_Destroy(net_info);
303
CONN_SetTimeout(conn, eIO_Open, net_info->timeout);
304
CONN_SetTimeout(conn, eIO_ReadWrite, net_info->timeout);
305
CONN_SetTimeout(conn, eIO_Close, net_info->timeout);
307
/* open ASN i/o, etc. */
308
result = (NI_HandPtr) MemNew(sizeof(NI_Handle));
309
result->extra_proc_info = conn;
310
result->raip = AsnIoNew(ASNIO_BIN | ASNIO_IN, (FILE*) 0,
311
(void*) conn, s_AsnRead, (IoFuncType) 0);
312
result->waip = AsnIoNew(ASNIO_BIN | ASNIO_OUT, (FILE*) 0,
313
(void*) conn, (IoFuncType) 0, s_AsnWrite);
314
AsnIoSetErrorMsg(result->raip, s_AsnErrorFunc);
315
AsnIoSetErrorMsg(result->waip, s_AsnErrorFunc);
316
result->hostname = StringSave(net_info->client_host);
318
disp->referenceCount++;
319
ConnNetInfo_Destroy(net_info);
325
static Int2 s_EndServices(NI_DispatcherPtr disp)
327
ASSERT ( disp->referenceCount > 0 );
328
if (--disp->referenceCount == 0) {
329
MemFree(disp->adminInfo);
337
static Int2 s_ServiceDisconnect(NI_HandPtr mhp)
339
s_EndServices(mhp->disp);
340
CONN_Close((CONN)mhp->extra_proc_info);
341
AsnIoClose(mhp->raip);
342
AsnIoClose(mhp->waip);
343
MemFree(mhp->hostname);
349
/* Exported table of interface functions
352
static const NIInterface s_NII_Service = {
359
const NIInterface *g_NII_Service = &s_NII_Service;