source: trunk/FACT++/dim/src/dns.c@ 18522

Last change on this file since 18522 was 18097, checked in by tbretz, 10 years ago
Updated to v20r13
File size: 45.0 KB
Line 
1/*
2 * DNS (Delphi Name Server) Package implements the name server for the DIM
3 * (Delphi Information Management) system
4 *
5 * Started date : 26-10-92
6 * Last modification : 02-08-94
7 * Written by : C. Gaspar
8 * Adjusted by : G.C. Ballintijn
9 *
10 */
11
12#define DNS
13#include <stdio.h>
14#include <dim.h>
15#include <dis.h>
16
17#ifndef WIN32
18#include <netdb.h>
19#endif
20/*
21#define MAX_HASH_ENTRIES 5000
22*/
23#define MAX_HASH_ENTRIES 25000
24FILE *foutptr;
25
26typedef struct node {
27 struct node *client_next;
28 struct node *client_prev;
29 struct node *next;
30 struct node *prev;
31 int conn_id;
32 int service_id;
33 struct serv *servp;
34} NODE;
35
36typedef struct red_node {
37 struct red_node *next;
38 struct red_node *prev;
39 int conn_id;
40 int service_id;
41 struct serv *servp;
42} RED_NODE;
43
44typedef struct serv {
45 struct serv *server_next;
46 struct serv *server_prev;
47 struct serv *next;
48 struct serv *prev;
49 char serv_name[MAX_NAME];
50 char serv_def[MAX_NAME];
51 int state;
52 int conn_id;
53 int server_format;
54 int serv_id;
55 RED_NODE *node_head;
56} DNS_SERVICE;
57
58typedef struct red_serv {
59 struct red_serv *next;
60 struct red_serv *prev;
61 char serv_name[MAX_NAME];
62 char serv_def[MAX_NAME];
63 int state;
64 int conn_id;
65 int server_format;
66 int serv_id;
67 RED_NODE *node_head;
68} RED_DNS_SERVICE;
69
70static DNS_SERVICE **Service_info_list;
71static RED_DNS_SERVICE *Service_hash_table[MAX_HASH_ENTRIES];
72static int Curr_n_services = 0;
73static int Curr_n_servers = 0;
74static int Last_conn_id;
75/*
76static int Debug = 2;
77*/
78static int Debug = 0;
79
80static int Timer_q;
81static int Server_info_id, Server_new_info_id,
82 Rpc_id, wake_up;
83
84static char RPC_dummy = 0;
85static char *Rpc_info = &RPC_dummy;
86static int Rpc_info_size = 0;
87
88static char DNS_accepted_domains[1024] = {0};
89static char DNS_accepted_nodes[1024] = {0};
90
91_DIM_PROTO( DNS_SERVICE *service_exists, (char *name) );
92_DIM_PROTO( void check_validity, (int conn_id) );
93_DIM_PROTO( void send_dns_server_info, (int conn_id, int **bufp, int *size) );
94_DIM_PROTO( void print_stats, (void) );
95_DIM_PROTO( void set_debug_on, (int level) );
96_DIM_PROTO( void set_debug_off, (void) );
97_DIM_PROTO( void kill_servers, (void) );
98_DIM_PROTO( void print_hash_table, (void) );
99_DIM_PROTO( void get_rpc_info, (int *tag, char **info, int *size) );
100_DIM_PROTO( void set_rpc_info, (int *tag, char *name, int *size) );
101_DIM_PROTO( void print_hash_table, (void) );
102_DIM_PROTO( static void release_conn, (int conn_id) );
103
104
105static void recv_rout( int conn_id, DIC_DNS_PACKET *packet, int size, int status )
106{
107 int handle_registration();
108 int handle_client_request();
109
110 if(size){}
111 switch(status)
112 {
113 case STA_DISC: /* connection broken */
114
115 if(Debug)
116 {
117 dim_print_date_time();
118 printf(" Disconnect received - conn: %d to %s@%s\n", conn_id,
119 Net_conns[conn_id].task,Net_conns[conn_id].node );
120 }
121
122 release_conn( conn_id );
123 break;
124 case STA_CONN: /* connection received */
125 if(Debug)
126 {
127 dim_print_date_time();
128 printf(" Connection request received - conn: %d\n", conn_id);
129 }
130 /* handle_conn( conn_id ); */
131 break;
132 case STA_DATA: /* normal packet */
133 switch( vtohl(packet->src_type) )
134 {
135 case SRC_DIS :
136 handle_registration(conn_id, (DIS_DNS_PACKET *)packet, 1);
137 break;
138 case SRC_DIC :
139 handle_client_request(conn_id,(DIC_DNS_PACKET *)packet);
140 break;
141 default:
142 dim_print_date_time();
143 printf(" conn: %d to %s@%s, Bad packet\n", conn_id,
144 Net_conns[conn_id].task,Net_conns[conn_id].node );
145 printf("packet->size = %d\n", vtohl(packet->size));
146 printf("packet->src_type = %d\n", vtohl(packet->src_type));
147 printf( "closing the connection.\n" );
148 fflush(stdout);
149 release_conn( conn_id );
150/*
151 panic( "recv_rout(): Bad switch(1)" );
152*/
153 }
154 break;
155 default:
156 dim_print_date_time();
157 printf( " - DIM panic: recv_rout(): Bad switch, exiting...\n");
158 abort();
159 }
160}
161
162static void error_handler(int conn_id, int severity, int errcode, char *reason)
163{
164 if(conn_id){}
165 if(errcode){}
166 dim_print_msg(reason, severity);
167/*
168 if(severity == 3)
169 {
170 printf("Exiting!\n");
171 exit(2);
172 }
173*/
174}
175
176int handle_registration( int conn_id, DIS_DNS_PACKET *packet, int tmout_flag )
177{
178 DNS_SERVICE *servp;
179 DNS_DIS_PACKET dis_packet;
180 int i, service_id;
181 int n_services;
182 char *ptr, *ptr1, *ptrt;
183 int found;
184 void do_update_did();
185 void do_inform_clients();
186 void inform_clients();
187 void service_init();
188 void service_insert();
189 void service_remove();
190#ifdef WIN32
191 extern int time();
192#endif
193#ifdef VMS
194 int format;
195#endif
196 int update_did = 0;
197 int name_too_long = 0;
198 int rem_only = 0;
199
200 Dns_conns[conn_id].validity = (int)time(NULL);
201 if( !Dns_conns[conn_id].service_head )
202 {
203
204 if(vtohl(packet->n_services) > 0)
205 {
206 service_id = vtohl(packet->services[0].service_id);
207 if((unsigned)service_id & 0x80000000)
208 rem_only = 1;
209 }
210/*
211 if( Debug )
212 {
213 dim_print_date_time();
214 printf( " !!!! New Conn %3d : Server %s@%s (PID %d) registering %d services, to delete %d\n",
215 conn_id, packet->task_name,
216 packet->node_name,
217 vtohl(packet->pid),
218 vtohl(packet->n_services), rem_only );
219 fflush(stdout);
220 }
221*/
222 if(rem_only)
223 return 0;
224
225 Dns_conns[conn_id].already = 0;
226 Dns_conns[conn_id].service_head =
227 (char *) malloc(sizeof(DNS_SERVICE));
228 dll_init( (DLL *) Dns_conns[conn_id].service_head );
229 Dns_conns[conn_id].n_services = 0;
230 Dns_conns[conn_id].timr_ent = NULL;
231 Curr_n_servers++;
232 Dns_conns[conn_id].src_type = SRC_DIS;
233 Dns_conns[conn_id].protocol = vtohl(packet->protocol);
234 strncpy( Dns_conns[conn_id].node_name, packet->node_name,
235 (size_t)MAX_NODE_NAME );
236 strncpy( Dns_conns[conn_id].task_name, packet->task_name,
237 (size_t)(MAX_TASK_NAME-4) );
238 strcpy(Dns_conns[conn_id].long_task_name, packet->task_name);
239 Dns_conns[conn_id].task_name[MAX_TASK_NAME-4-1] = '\0';
240 for(i = 0; i < 4; i++)
241 Dns_conns[conn_id].node_addr[i] = packet->node_addr[i];
242 Dns_conns[conn_id].pid = vtohl(packet->pid);
243 Dns_conns[conn_id].port = vtohl(packet->port);
244/*
245 if( Debug )
246 {
247 dim_print_date_time();
248 printf( " !!!! New Conn %3d : Server %s@%s (PID %d) registered %d services\n",
249 conn_id, Dns_conns[conn_id].task_name,
250 Dns_conns[conn_id].node_name,
251 Dns_conns[conn_id].pid,
252 vtohl(packet->n_services) );
253 fflush(stdout);
254 }
255*/
256
257
258 if(strcmp(Dns_conns[conn_id].task_name,"DIS_DNS"))
259 if(DNS_accepted_domains[0] == 0)
260 {
261 if(!get_dns_accepted_domains(DNS_accepted_domains))
262 DNS_accepted_domains[0] = (char)0xFF;
263 }
264 if((DNS_accepted_domains[0] != (char)0xFF) && (strcmp(Dns_conns[conn_id].task_name,"DIS_DNS")))
265 {
266 ptr = DNS_accepted_domains;
267 found = 0;
268 while(*ptr)
269 {
270 ptr1 = strchr(ptr,',');
271 if(ptr1)
272 {
273 *ptr1 = '\0';
274 ptr1++;
275 }
276 else
277 {
278 ptr1 = ptr;
279 ptr1 += (int)strlen(ptr);
280 }
281 if(strstr(Dns_conns[conn_id].node_name,ptr))
282 {
283 found = 1;
284 break;
285 }
286 ptr = ptr1;
287 }
288 if(!found)
289 {
290 dis_packet.type = htovl(DNS_DIS_STOP);
291 dis_packet.size = htovl(DNS_DIS_HEADER);
292 if( !dna_write_nowait(conn_id, &dis_packet, DNS_DIS_HEADER) )
293 {
294 dim_print_date_time();
295 printf(" Stop Server: Couldn't write, releasing %d\n",conn_id);
296 fflush(stdout);
297 }
298 dim_print_date_time();
299 printf(" Connection from %s refused, stopping server %s\n",
300 Dns_conns[conn_id].node_name,
301 Dns_conns[conn_id].task_name);
302 fflush(stdout);
303 release_conn(conn_id);
304
305 return 0;
306 }
307 }
308 if(tmout_flag)
309 Dns_conns[conn_id].timr_ent = dtq_add_entry( Timer_q,
310 (int)(WATCHDOG_TMOUT_MAX * 1.3), check_validity, conn_id);
311 if(strcmp(Dns_conns[conn_id].task_name,"DIS_DNS"))
312 {
313 dna_set_test_write(conn_id, dim_get_keepalive_timeout());
314 }
315 Dns_conns[conn_id].old_n_services = 0;
316/*
317 Dns_conns[conn_id].n_services = 1;
318 do_update_did(conn_id);
319*/
320 update_did = 1;
321/*
322 Dns_conns[conn_id].old_n_services = 0;
323*/
324 Dns_conns[conn_id].n_services = 0;
325 }
326 else
327 {
328 if( (Dns_conns[conn_id].n_services == -1) &&
329 vtohl(packet->n_services) )
330 {
331 if(strcmp(Dns_conns[conn_id].task_name,"DIS_DNS"))
332 dna_set_test_write(conn_id, dim_get_keepalive_timeout());
333 dim_print_date_time();
334 printf( " Server %s out of error\n",
335 Dns_conns[conn_id].task_name );
336 fflush(stdout);
337 Dns_conns[conn_id].n_services = 0;
338 }
339 }
340 n_services = vtohl(packet->n_services);
341 if((int)strlen(Dns_conns[conn_id].task_name) == MAX_TASK_NAME-4-1)
342 name_too_long = 1;
343 for( i = 0; i < n_services; i++ )
344 {
345/*
346 if( Debug )
347 {
348 dim_print_date_time();
349 printf( " Conn %3d : Server %s@%s (PID %d) registered %s\n",
350 conn_id, Dns_conns[conn_id].task_name,
351 Dns_conns[conn_id].node_name,
352 Dns_conns[conn_id].pid,
353 packet->services[i].service_name );
354 fflush(stdout);
355 }
356*/
357 if(n_services == 1)
358 {
359 if(!strcmp(packet->services[i].service_name, "DUMMY_UPDATE_PACKET"))
360 {
361 do_inform_clients(conn_id);
362 break;
363 }
364 }
365 if( (servp = service_exists(packet->services[i].service_name)) )
366 {
367 /* if service available on another server send kill signal */
368 if((servp->conn_id) && (servp->conn_id != conn_id))
369 {
370 dis_packet.type = htovl(DNS_DIS_KILL);
371 dis_packet.size = htovl(DNS_DIS_HEADER);
372#ifdef VMS
373 format = vtohl(packet->format);
374 if((format & MY_OS9) || (servp->state == -1))
375 {
376 Dns_conns[servp->conn_id].already = 1;
377 if( !dna_write(servp->conn_id, &dis_packet, DNS_DIS_HEADER) )
378 {
379 dim_print_date_time();
380 printf(" Couldn't write, releasing %d\n",servp->conn_id);
381 fflush(stdout);
382 }
383 dim_print_date_time();
384 printf(" Service %s already declared, killing server %s\n",
385 servp->serv_name, Dns_conns[servp->conn_id].task_name);
386 fflush(stdout);
387 release_client(servp->conn_id);
388 release_conn(servp->conn_id);
389 }
390 else
391 {
392#endif
393 if((Dns_conns[servp->conn_id].port == Dns_conns[conn_id].port) &&
394 (!strcmp(Dns_conns[servp->conn_id].node_name, Dns_conns[conn_id].node_name)))
395 {
396 dim_print_date_time();
397printf(" Service %s already declared by conn %d - %s@%s:%d (PID %d), Redeclared by conn %d - %s@%s:%d (PID %d)(same server) - Closing both conns %d %d\n",
398 servp->serv_name, servp->conn_id,
399 Dns_conns[servp->conn_id].task_name,
400 Dns_conns[servp->conn_id].node_name,
401 Dns_conns[servp->conn_id].port,
402 Dns_conns[servp->conn_id].pid,
403 conn_id,
404 Dns_conns[conn_id].task_name,
405 Dns_conns[conn_id].node_name,
406 Dns_conns[conn_id].port,
407 Dns_conns[conn_id].pid,
408 servp->conn_id, conn_id);
409 fflush(stdout);
410 release_conn(servp->conn_id);
411 release_conn(conn_id);
412/*
413 update_did = 0;
414*/
415 return(0);
416
417 }
418 else
419 {
420 Dns_conns[conn_id].already = 1;
421
422 if( !dna_write_nowait(conn_id, &dis_packet, DNS_DIS_HEADER) )
423 {
424 dim_print_date_time();
425 printf(" Kill Server: Couldn't write, releasing %d\n",conn_id);
426 fflush(stdout);
427 }
428 dim_print_date_time();
429printf(" Service %s already declared by conn %d - %s@%s:%d (PID %d), killing server conn %d - %s@%s:%d (PID %d) \n",
430 servp->serv_name, servp->conn_id,
431 Dns_conns[servp->conn_id].task_name,
432 Dns_conns[servp->conn_id].node_name,
433 Dns_conns[servp->conn_id].port,
434 Dns_conns[servp->conn_id].pid,
435 conn_id,
436 Dns_conns[conn_id].task_name,
437 Dns_conns[conn_id].node_name,
438 Dns_conns[conn_id].port,
439 Dns_conns[conn_id].pid);
440 fflush(stdout);
441
442 release_conn(conn_id);
443
444 return(0);
445 }
446#ifdef VMS
447 }
448#endif
449 }
450 else if( servp->state != -1 )
451 {
452 if( !dll_empty((DLL *) servp->node_head))
453 {
454 /*there are interested clients waiting*/
455 strncpy( servp->serv_def,
456 packet->services[i].service_def,(size_t)MAX_NAME );
457 servp->conn_id = conn_id;
458 servp->state = 1;
459 servp->server_format = vtohl(packet->format);
460 servp->serv_id = vtohl(packet->services[i].service_id);
461 dll_insert_queue((DLL *)
462 Dns_conns[conn_id].service_head,
463 (DLL *) servp);
464 Dns_conns[conn_id].n_services++;
465
466/*
467 if(n_services == 1)
468*/
469 if(n_services < MAX_REGISTRATION_UNIT)
470 {
471 inform_clients(servp);
472 }
473 continue;
474 }
475 else
476 {
477 /* test if Service is to be removed */
478 service_id = vtohl(packet->services[i].service_id);
479 if((unsigned)service_id & 0x80000000)
480 {
481 dll_remove((DLL *) servp);
482 service_remove(&(servp->next));
483 Curr_n_services--;
484 free(servp);
485 Dns_conns[conn_id].n_services--;
486 if( dll_empty((DLL *) Dns_conns[conn_id].service_head))
487 {
488 if( Debug )
489 {
490 dim_print_date_time();
491 printf( " Conn %3d : Server %s@%s unregistered All services, releasing it.\n",
492 conn_id, Dns_conns[conn_id].task_name,
493 Dns_conns[conn_id].node_name );
494 fflush(stdout);
495 }
496 release_conn(conn_id);
497 return(0);
498 }
499 continue;
500 }
501 }
502 }
503 else
504 {
505 servp->state = 1;
506 Dns_conns[conn_id].n_services++;
507/*
508 if(n_services == 1)
509*/
510 if(n_services < MAX_REGISTRATION_UNIT)
511 {
512 if( !dll_empty((DLL *) servp->node_head) )
513 {
514 inform_clients( servp );
515 }
516 }
517 continue;
518 }
519
520 }
521 if(!(servp = service_exists(packet->services[i].service_name)))
522 {
523 servp = (DNS_SERVICE *)malloc(sizeof(DNS_SERVICE));
524 if(name_too_long)
525 {
526 if(strstr(packet->services[i].service_name,"/CLIENT_LIST"))
527 {
528 strncpy(Dns_conns[conn_id].long_task_name, packet->services[i].service_name,
529 (size_t)MAX_NAME);
530 ptrt = strstr(Dns_conns[conn_id].long_task_name,"/CLIENT_LIST");
531 *ptrt = '\0';
532 }
533 }
534 strncpy( servp->serv_name,
535 packet->services[i].service_name,
536 (size_t)MAX_NAME );
537 strncpy( servp->serv_def,
538 packet->services[i].service_def,
539 (size_t)MAX_NAME );
540 servp->state = 1;
541 servp->conn_id = conn_id;
542 servp->server_format = vtohl(packet->format);
543 servp->serv_id = vtohl(packet->services[i].service_id);
544 dll_insert_queue( (DLL *)
545 Dns_conns[conn_id].service_head,
546 (DLL *) servp );
547 Dns_conns[conn_id].n_services++;
548 service_insert( &(servp->next) );
549 servp->node_head = (RED_NODE *) malloc(sizeof(NODE));
550 dll_init( (DLL *) servp->node_head );
551 Curr_n_services++;
552 }
553 }
554 if(update_did)
555 do_update_did(conn_id);
556 if( Debug )
557 {
558 if(vtohl(packet->n_services) != 0)
559 {
560 dim_print_date_time();
561 printf( " Conn %3d : Server %s@%s (PID %d) registered %d services\n",
562 conn_id, Dns_conns[conn_id].task_name,
563 Dns_conns[conn_id].node_name,
564 Dns_conns[conn_id].pid,
565 vtohl(packet->n_services) );
566 fflush(stdout);
567 }
568 }
569
570 return(1);
571}
572
573void update_did()
574{
575 int i;
576 void do_update_did();
577
578 for(i = 0; i< Curr_N_Conns; i++)
579 {
580 if(Dns_conns[i].src_type == SRC_DIS)
581 {
582 do_update_did(i);
583 }
584 }
585}
586
587void do_update_did(int conn_id)
588{
589 int n_services, old_n_services;
590
591 n_services = Dns_conns[conn_id].n_services;
592/*
593 if(Dns_conns[conn_id].n_services)
594 {
595*/
596 old_n_services = Dns_conns[conn_id].old_n_services;
597 if(old_n_services != n_services)
598 {
599 Last_conn_id = conn_id;
600 if((old_n_services <= 0) || (n_services == 0) || (n_services == -1))
601 dis_update_service(Server_new_info_id);
602 dis_update_service(Server_info_id);
603 Dns_conns[conn_id].old_n_services = Dns_conns[conn_id].n_services;
604 }
605/*
606 }
607*/
608}
609
610void check_validity(int conn_id)
611{
612 int time_diff;
613 DNS_DIS_PACKET dis_packet;
614 void set_in_error();
615
616 if(Dns_conns[conn_id].validity < 0)
617 {
618 /* timeout reached kill all services and connection */
619 if(Dns_conns[conn_id].n_services != -1)
620 {
621 dim_print_date_time();
622 printf(" Server %s (%s@%s) has been set in error\n",
623 Dns_conns[conn_id].task_name, Net_conns[conn_id].task, Net_conns[conn_id].node);
624 fflush(stdout);
625 set_in_error(conn_id);
626 return;
627 }
628/*
629 Dns_conns[conn_id].validity = -Dns_conns[conn_id].validity;
630*/
631 }
632 time_diff = (int)time(NULL) - Dns_conns[conn_id].validity;
633 if(time_diff > (int)(WATCHDOG_TMOUT_MAX*1.2))
634 {
635 /* send register signal */
636 dis_packet.type = htovl(DNS_DIS_REGISTER);
637 dis_packet.size = htovl(DNS_DIS_HEADER);
638 if(Debug)
639 {
640 dim_print_date_time();
641 printf(" Conn %3d : Server %s@%s Registration Requested\n",
642 conn_id, Net_conns[conn_id].task, Net_conns[conn_id].node);
643 fflush(stdout);
644 }
645/* moved from dna_write to dna_write_nowait in 14/10/2008 */
646 if( !dna_write_nowait(conn_id, &dis_packet, DNS_DIS_HEADER) )
647 {
648 dim_print_date_time();
649 printf(" Server Validity: Couldn't write, releasing Conn %3d : Server %s@%s\n",conn_id,
650 Net_conns[conn_id].task, Net_conns[conn_id].node);
651 fflush(stdout);
652 release_conn(conn_id);
653 }
654 else
655 Dns_conns[conn_id].validity = -Dns_conns[conn_id].validity;
656 }
657}
658
659
660int handle_client_request( int conn_id, DIC_DNS_PACKET *packet )
661{
662 DNS_SERVICE *servp;
663 NODE *nodep;
664 RED_NODE *red_nodep;
665 int i, service_id;
666 DNS_DIC_PACKET dic_packet;
667 SERVICE_REG *serv_regp;
668 void service_insert();
669 void service_remove();
670 void tcpip_get_addresses();
671 char *ptr, *ptr1;
672 int found;
673
674 serv_regp = (SERVICE_REG *)(&(packet->service));
675 if(Debug)
676 {
677 dim_print_date_time();
678 printf(" Conn %3d : Client %s@%s requested %s\n",
679 conn_id, Net_conns[conn_id].task, Net_conns[conn_id].node,
680 serv_regp->service_name);
681 fflush(stdout);
682 }
683
684 if(DNS_accepted_nodes[0] == 0)
685 {
686 if(!get_dns_accepted_nodes(DNS_accepted_nodes))
687 DNS_accepted_nodes[0] = (char)0xFF;
688 }
689 if(DNS_accepted_nodes[0] != (char)0xFF)
690 {
691 ptr = DNS_accepted_nodes;
692 found = 0;
693 while(*ptr)
694 {
695 ptr1 = strchr(ptr,',');
696 if(ptr1)
697 {
698 *ptr1 = '\0';
699 ptr1++;
700 }
701 else
702 {
703 ptr1 = ptr;
704 ptr1 += (int)strlen(ptr);
705 }
706 if(strstr(Net_conns[conn_id].node,ptr))
707 {
708 found = 1;
709 break;
710 }
711 ptr = ptr1;
712 }
713 if(!found)
714 {
715 dic_packet.service_id = serv_regp->service_id;
716 dic_packet.node_name[0] = (char)0xFF;
717 dic_packet.task_name[0] = 0;
718 dic_packet.node_addr[0] = 0;
719 dic_packet.pid = 0;
720 dic_packet.size = htovl(DNS_DIC_HEADER);
721 dim_print_date_time();
722 printf(" Connection from %s refused, stopping client pid=%s\n",
723 Net_conns[conn_id].node,
724 Net_conns[conn_id].task);
725 fflush(stdout);
726 if( !dna_write_nowait(conn_id, &dic_packet, DNS_DIC_HEADER) )
727 {
728 dim_print_date_time();
729 printf(" Stop Client: Couldn't write, releasing Conn %3d : Client %s@%s\n",conn_id,
730 Net_conns[conn_id].task,
731 Net_conns[conn_id].node);
732 fflush(stdout);
733 }
734 release_conn(conn_id);
735
736 return 0;
737 }
738 }
739
740 service_id = vtohl(serv_regp->service_id);
741 if( service_id == -1 ) /* remove service */
742 {
743 if(Debug)
744 {
745 printf("\tRemoving Request\n");
746 fflush(stdout);
747 }
748 if( (servp = service_exists(serv_regp->service_name)) )
749 {
750 red_nodep = servp->node_head;
751 while( (red_nodep =
752 (RED_NODE *) dll_get_next(
753 (DLL *) servp->node_head,
754 (DLL *) red_nodep)) )
755 {
756 if( red_nodep->conn_id == conn_id )
757 {
758 dll_remove((DLL *) red_nodep);
759 ptr = (char *)red_nodep - (2 * sizeof(void *));
760 nodep = (NODE *)ptr;
761 dll_remove((DLL *) nodep);
762 red_nodep = red_nodep->prev;
763 free(nodep);
764 break;
765 }
766 }
767 if(( dll_empty((DLL *) servp->node_head) ) && (servp->state == 0))
768 {
769 if(Debug)
770 {
771 printf("\tand Removing Service\n");
772 fflush(stdout);
773 }
774 service_remove(&(servp->next));
775 Curr_n_services--;
776 free(servp);
777 }
778 }
779 return(0);
780 }
781 if( (unsigned)service_id & 0x80000000 ) /* remove service */
782 {
783 service_id &= 0x7fffffff;
784 if(Debug)
785 {
786 printf("\tRemoving Request\n");
787 fflush(stdout);
788 }
789 if( (servp = service_exists(serv_regp->service_name)) )
790 {
791 red_nodep = servp->node_head;
792 while( (red_nodep =
793 (RED_NODE *) dll_get_next(
794 (DLL *) servp->node_head,
795 (DLL *) red_nodep)) )
796 {
797 if(( red_nodep->conn_id == conn_id ) &&
798 ( red_nodep->service_id == service_id ) )
799 {
800 dll_remove((DLL *) red_nodep);
801 ptr = (char *)red_nodep - (2 * sizeof(void *));
802 nodep = (NODE *)ptr;
803 dll_remove((DLL *) nodep);
804 red_nodep = red_nodep->prev;
805 free(nodep);
806 break;
807 }
808 }
809 if(( dll_empty((DLL *) servp->node_head) ) && (servp->state == 0))
810 {
811 if(Debug)
812 {
813 printf("\tand Removing Service\n");
814 fflush(stdout);
815 }
816 service_remove(&(servp->next));
817 Curr_n_services--;
818 free(servp);
819 }
820 }
821 return(0);
822 }
823 /* Is already in v.format */
824 dic_packet.service_id = serv_regp->service_id;
825 dic_packet.node_name[0] = 0;
826 dic_packet.task_name[0] = 0;
827 dic_packet.node_addr[0] = 0;
828 dic_packet.pid = 0;
829 dic_packet.size = htovl(DNS_DIC_HEADER);
830 if( Dns_conns[conn_id].src_type == SRC_NONE )
831 dna_set_test_write(conn_id, dim_get_keepalive_timeout());
832 if( !(servp = service_exists(serv_regp->service_name)) )
833 {
834 if(Debug)
835 {
836 printf("\tService does not exist, queueing request\n");
837 fflush(stdout);
838 }
839 if( !Dns_conns[conn_id].node_head )
840 {
841 Dns_conns[conn_id].src_type = SRC_DIC;
842 Dns_conns[conn_id].node_head =
843 malloc(sizeof(NODE));
844 dll_init( (DLL *) Dns_conns[conn_id].node_head );
845 }
846 servp = (DNS_SERVICE *) malloc(sizeof(DNS_SERVICE));
847 strncpy( servp->serv_name, serv_regp->service_name, (size_t)MAX_NAME );
848 servp->serv_def[0] = '\0';
849 servp->state = 0;
850 servp->conn_id = 0;
851 service_insert(&(servp->next));
852 Curr_n_services++;
853 servp->node_head = (RED_NODE *)malloc(sizeof(NODE));
854 dll_init( (DLL *) servp->node_head );
855 nodep = (NODE *)malloc(sizeof(NODE));
856 nodep->conn_id = conn_id;
857 nodep->service_id = service_id;
858 nodep->servp = servp;
859 dll_insert_queue((DLL *) Dns_conns[conn_id].node_head,
860 (DLL *) nodep);
861 dll_insert_queue((DLL *) servp->node_head,
862 (DLL *) &(nodep->next));
863 }
864 else
865 {
866 if( servp->state == 1 )
867 {
868#ifdef VMS
869 if(servp->server_format & MY_OS9)
870 {
871 dna_test_write(servp->conn_id);
872 }
873#endif
874 Dns_conns[conn_id].src_type = SRC_DIC;
875 strcpy( dic_packet.node_name,
876 Dns_conns[servp->conn_id].node_name );
877 strcpy( dic_packet.task_name,
878 Dns_conns[servp->conn_id].task_name );
879 for(i = 0; i < 4; i++)
880 dic_packet.node_addr[i] =
881 Dns_conns[servp->conn_id].node_addr[i];
882 dic_packet.port = htovl(Dns_conns[servp->conn_id].port);
883 dic_packet.pid = htovl(Dns_conns[servp->conn_id].pid);
884 dic_packet.protocol = htovl(Dns_conns[servp->conn_id].protocol);
885 dic_packet.format = htovl(servp->server_format);
886 strcpy( dic_packet.service_def, servp->serv_def );
887 if(Debug)
888 {
889 printf("\tService exists in %s@%s, port = %d\n",
890 dic_packet.task_name, dic_packet.node_name,
891 dic_packet.port);
892 fflush(stdout);
893 }
894 }
895 else
896 {
897 if(Debug)
898 {
899 if(servp->state == -1)
900 {
901 printf("\tService exists in BAD state, queueing request\n");
902 fflush(stdout);
903 }
904 else
905 {
906 printf("\tService does not exist (other client(s) waiting), queueing request\n");
907 fflush(stdout);
908 }
909 }
910 if(!(NODE *)Dns_conns[conn_id].node_head )
911 {
912 Dns_conns[conn_id].src_type = SRC_DIC;
913 Dns_conns[conn_id].node_head =
914 (char *) malloc(sizeof(NODE));
915 dll_init((DLL *)Dns_conns[conn_id].node_head);
916 }
917 nodep = (NODE *)malloc(sizeof(NODE));
918 nodep->conn_id = conn_id;
919 nodep->service_id = service_id;
920 nodep->servp = servp;
921 dll_insert_queue((DLL *) Dns_conns[conn_id].node_head,
922 (DLL *) nodep);
923 dll_insert_queue((DLL *) servp->node_head,
924 (DLL *) &(nodep->next));
925 }
926 }
927/* Should it be dna_write_nowait? 16/9/2008 */
928/* moved from dna_write to dna_write_nowait in 14/10/2008 */
929 if( !dna_write_nowait(conn_id, &dic_packet, DNS_DIC_HEADER) )
930 {
931 dim_print_date_time();
932 printf(" Client Request: Couldn't write, releasing Conn %3d : Client %s@%s\n",conn_id,
933 Net_conns[conn_id].task,
934 Net_conns[conn_id].node);
935 fflush(stdout);
936 release_conn(conn_id);
937 }
938
939 return(1);
940}
941
942void do_inform_clients(int conn_id)
943{
944 DNS_SERVICE *servp;
945 int n_informed = 0;
946 static DNS_SERVICE *prev_servp = (DNS_SERVICE *)0;
947 void inform_clients();
948
949 DISABLE_AST
950 if(!Dns_conns[conn_id].service_head)
951 {
952 prev_servp = (DNS_SERVICE *)0;
953 ENABLE_AST
954 return;
955 }
956 if(prev_servp)
957 servp = prev_servp;
958 else
959 servp = (DNS_SERVICE *)Dns_conns[conn_id].service_head;
960 while( (servp = (DNS_SERVICE *) dll_get_next(
961 (DLL *) Dns_conns[conn_id].service_head,
962 (DLL *) servp)) )
963 {
964 if( servp->state != -1 )
965 {
966 if( !dll_empty((DLL *) servp->node_head))
967 {
968 inform_clients(servp);
969 n_informed++;
970 if(n_informed == 1000)
971 {
972 dtq_start_timer(0, do_inform_clients, conn_id);
973 ENABLE_AST
974 return;
975 }
976 }
977 }
978 }
979 prev_servp = (DNS_SERVICE *)0;
980 ENABLE_AST
981}
982
983
984void inform_clients(DNS_SERVICE *servp)
985{
986 RED_NODE *nodep, *prevp;
987 NODE *full_nodep;
988 DNS_DIC_PACKET packet;
989 char *ptr;
990 int i, to_release = 0;
991
992 nodep = servp->node_head;
993 prevp = nodep;
994 while( (nodep = (RED_NODE *) dll_get_next((DLL *) servp->node_head,
995 (DLL *) prevp)) )
996 {
997 packet.service_id = htovl(nodep->service_id);
998 strcpy(packet.node_name, Dns_conns[servp->conn_id].node_name);
999 strcpy(packet.task_name, Dns_conns[servp->conn_id].task_name);
1000 for(i = 0; i < 4; i++)
1001 packet.node_addr[i] = Dns_conns[servp->conn_id].node_addr[i];
1002 packet.port = htovl(Dns_conns[servp->conn_id].port);
1003 packet.pid = htovl(Dns_conns[servp->conn_id].pid);
1004 packet.protocol = htovl(Dns_conns[servp->conn_id].protocol);
1005 packet.size = htovl(DNS_DIC_HEADER);
1006 packet.format = htovl(servp->server_format);
1007 strcpy( packet.service_def, servp->serv_def );
1008/* Should it be dna_write_nowait? 16/9/2008 */
1009/* moved from dna_write to dna_write_nowait in 14/10/2008 */
1010/*
1011 dna_write_nowait(nodep->conn_id, &packet, DNS_DIC_HEADER);
1012*/
1013 if( !dna_write_nowait(nodep->conn_id, &packet, DNS_DIC_HEADER) )
1014 {
1015 dim_print_date_time();
1016 printf(" Inform Client: Couldn't write, releasing Conn %3d : Client %s@%s\n",nodep->conn_id,
1017 Net_conns[nodep->conn_id].task,
1018 Net_conns[nodep->conn_id].node);
1019 fflush(stdout);
1020 to_release = nodep->conn_id;
1021/*
1022release_conn(nodep->conn_id);
1023*/
1024 }
1025/*
1026 if(dna_write_nowait(nodep->conn_id, &packet, DNS_DIC_HEADER))
1027 {
1028*/
1029 dll_remove( (DLL *) nodep );
1030 ptr = (char *)nodep - (2 * sizeof(void *));
1031 full_nodep = (NODE *)ptr;
1032 dll_remove( (DLL *) full_nodep );
1033 nodep = nodep->prev;
1034 free( full_nodep );
1035 prevp = nodep;
1036/*
1037 }
1038*/
1039 }
1040 if(to_release)
1041 release_conn(to_release);
1042}
1043
1044#ifdef VMS
1045static release_client(int conn_id)
1046{
1047char *ptr_task;
1048char *ptr_node;
1049int i;
1050
1051 ptr_task = Net_conns[conn_id].task;
1052 ptr_node = Net_conns[conn_id].node;
1053 for( i = 0; i< Curr_N_Conns; i++ )
1054 {
1055 if( (!strcmp(Net_conns[i].task,ptr_task)) &&
1056 (!strcmp(Net_conns[i].node,ptr_node)) )
1057 {
1058 if(i != conn_id)
1059 {
1060 if( Dns_conns[i].src_type == SRC_DIC )
1061 {
1062 if(Debug)
1063 {
1064 dim_print_date_time();
1065 printf(" Releasing client on conn %d - %s@%s\n",
1066 i, Net_conns[i].task, Net_conns[i].node);
1067 fflush(stdout);
1068 }
1069 release_conn(i);
1070 }
1071 }
1072 }
1073 }
1074}
1075#endif
1076
1077static void release_conn(int conn_id)
1078{
1079 DNS_SERVICE *servp, *old_servp;
1080 NODE *nodep, *old_nodep;
1081 void service_remove();
1082
1083 servp = (DNS_SERVICE *)Dns_conns[conn_id].service_head;
1084 nodep = (NODE *)Dns_conns[conn_id].node_head;
1085 if(( Dns_conns[conn_id].src_type == SRC_DIS ) || (servp))
1086 {
1087 if( Debug )
1088 {
1089 dim_print_date_time();
1090 printf( " Conn %3d : Server %s@%s died\n",
1091 conn_id, Dns_conns[conn_id].task_name,
1092 Dns_conns[conn_id].node_name);
1093 fflush(stdout);
1094 }
1095 else
1096 {
1097 if(Dns_conns[conn_id].n_services == -1)
1098 {
1099 dim_print_date_time();
1100 printf( " Conn %3d : Server %s@%s died\n",
1101 conn_id, Dns_conns[conn_id].task_name,
1102 Dns_conns[conn_id].node_name);
1103 fflush(stdout);
1104 }
1105 }
1106 Curr_n_servers--;
1107 if( Dns_conns[conn_id].timr_ent )
1108 {
1109 dtq_rem_entry( Timer_q, Dns_conns[conn_id].timr_ent );
1110 Dns_conns[conn_id].timr_ent = NULL;
1111 }
1112 servp = (DNS_SERVICE *)Dns_conns[conn_id].service_head;
1113 while( (servp = (DNS_SERVICE *) dll_get_next(
1114 (DLL *) Dns_conns[conn_id].service_head,
1115 (DLL *) servp)) )
1116 {
1117 dll_remove((DLL *) servp);
1118 if(dll_empty((DLL *) servp->node_head))
1119 {
1120 service_remove(&(servp->next));
1121 Curr_n_services--;
1122 old_servp = servp;
1123 servp = servp->server_prev;
1124 free(old_servp);
1125 }
1126 else
1127 {
1128 servp->state = 0;
1129 servp->conn_id = 0;
1130 servp = servp->server_prev;
1131 }
1132 }
1133 if(Dns_conns[conn_id].n_services)
1134 {
1135 Dns_conns[conn_id].n_services = 0;
1136
1137 do_update_did(conn_id);
1138/*
1139 Last_conn_id = conn_id;
1140 dis_update_service(Server_new_info_id);
1141 dis_update_service(Server_info_id);
1142*/
1143 }
1144 free((DNS_SERVICE *)Dns_conns[conn_id].service_head);
1145 Dns_conns[conn_id].service_head = 0;
1146 Dns_conns[conn_id].src_type = SRC_NONE;
1147 dna_close(conn_id);
1148 }
1149 else if((Dns_conns[conn_id].src_type == SRC_DIC) || (nodep))
1150 {
1151 if(Debug)
1152 {
1153 dim_print_date_time();
1154 printf(" Conn %3d : Client %s@%s died\n",
1155 conn_id, Net_conns[conn_id].task, Net_conns[conn_id].node);
1156 fflush(stdout);
1157 }
1158 if( (nodep = (NODE *)Dns_conns[conn_id].node_head) )
1159 {
1160 while( (nodep = (NODE *) dll_get_next(
1161 (DLL *) Dns_conns[conn_id].node_head,
1162 (DLL *) nodep)) )
1163 {
1164 servp = nodep->servp;
1165 dll_remove( (DLL *) nodep );
1166 dll_remove( (DLL *) &(nodep->next) );
1167 old_nodep = nodep;
1168 nodep = nodep->client_prev;
1169 free(old_nodep);
1170 if( (dll_empty((DLL *) servp->node_head)) &&
1171 (!servp->conn_id) )
1172 {
1173 service_remove(&(servp->next));
1174 Curr_n_services--;
1175 free( servp );
1176 }
1177 }
1178 free(Dns_conns[conn_id].node_head);
1179 Dns_conns[conn_id].node_head = 0;
1180 }
1181 Dns_conns[conn_id].src_type = SRC_NONE;
1182 dna_close(conn_id);
1183 }
1184 else
1185 {
1186 if(Debug)
1187 {
1188 dim_print_date_time();
1189 printf(" Conn %3d : Undefined Type %s@%s died\n",
1190 conn_id, Net_conns[conn_id].task,
1191 Net_conns[conn_id].node);
1192 fflush(stdout);
1193 }
1194 dna_close(conn_id);
1195 }
1196}
1197
1198
1199void set_in_error(int conn_id)
1200{
1201 DNS_SERVICE *servp;
1202
1203 if(Dns_conns[conn_id].src_type == SRC_DIS)
1204 {
1205 if(strcmp(Dns_conns[conn_id].task_name,"DIS_DNS"))
1206 dna_rem_test_write(conn_id);
1207 servp = (DNS_SERVICE *)Dns_conns[conn_id].service_head;
1208 while( (servp = (DNS_SERVICE *) dll_get_next(
1209 (DLL *) Dns_conns[conn_id].service_head,
1210 (DLL *) servp)) )
1211 servp->state = -1;
1212 Dns_conns[conn_id].n_services = -1;
1213 }
1214}
1215
1216void get_dns_server_info(int *tag, int **bufp, int *size, int *first_time)
1217{
1218 if(tag){}
1219 if(*first_time)
1220 {
1221
1222#ifdef VMS
1223 sys$wake(0, 0);
1224#else
1225 wake_up = TRUE;
1226#ifdef WIN32
1227 wake_up();
1228#endif
1229#endif
1230 *size = 0;
1231 }
1232 else
1233 {
1234 send_dns_server_info(Last_conn_id, bufp, size);
1235 }
1236}
1237
1238
1239void send_dns_server_info(int conn_id, int **bufp, int *size)
1240{
1241 static int curr_allocated_size = 0;
1242 static DNS_DID *dns_info_buffer;
1243 DNS_SERVICE *servp;
1244 DNS_SERVER_INFO *dns_server_info;
1245 DNS_SERVICE_INFO *dns_service_info;
1246 DNS_CONNECTION *connp;
1247 int max_size;
1248 int n_services;
1249
1250 DISABLE_AST
1251 connp = &Dns_conns[conn_id];
1252 if(connp->src_type != SRC_DIS)
1253 {
1254 ENABLE_AST
1255 return;
1256 }
1257 n_services = connp->n_services;
1258 if(n_services == -1)
1259 n_services = 0;
1260 max_size = (int)sizeof(DNS_SERVER_INFO) +
1261 n_services * (int)sizeof(DNS_SERVICE_INFO);
1262 if(!curr_allocated_size)
1263 {
1264 dns_info_buffer = (DNS_DID *)malloc((size_t)max_size);
1265 curr_allocated_size = max_size;
1266 }
1267 else if (max_size > curr_allocated_size)
1268 {
1269 free(dns_info_buffer);
1270 dns_info_buffer = (DNS_DID *)malloc((size_t)max_size);
1271 curr_allocated_size = max_size;
1272 }
1273 dns_server_info = &dns_info_buffer->server;
1274 dns_service_info = dns_info_buffer->services;
1275 strncpy(dns_server_info->task, connp->task_name, (size_t)(MAX_TASK_NAME-4));
1276 strncpy(dns_server_info->node, connp->node_name, (size_t)MAX_NODE_NAME);
1277 dns_server_info->pid = htovl(connp->pid);
1278 dns_server_info->n_services = htovl(connp->n_services);
1279 servp = (DNS_SERVICE *)connp->service_head;
1280 while( (servp = (DNS_SERVICE *) dll_get_next((DLL *) connp->service_head,
1281 (DLL *) servp)) )
1282 {
1283 strncpy(dns_service_info->name, servp->serv_name, (size_t)MAX_NAME);
1284 dns_service_info->status = htovl(1);
1285 if(servp->serv_id & 0x10000000)
1286 dns_service_info->type = htovl(1);
1287 else
1288 dns_service_info->type = htovl(0);
1289 dns_service_info++;
1290 }
1291 *bufp = (int *)dns_info_buffer;
1292 *size = max_size;
1293 ENABLE_AST
1294}
1295
1296void get_new_dns_server_info(int *tag, int **bufp, int *size, int *first_time)
1297{
1298 static int curr_allocated_size = 0;
1299 static char *info_buffer;
1300 static int *pid_buffer, pid_size;
1301 int pid_index = 0;
1302 DNS_CONNECTION *connp;
1303 int i, max_size, max_pid_size/*, j, n*/;
1304 int n_server = 0;
1305 char /*aux[MAX_NAME], *ptr, */ server[MAX_NAME], *info_buffer_ptr;
1306/*
1307 DNS_SERVICE *servp;
1308 int find_services();
1309*/
1310
1311 DISABLE_AST
1312 if(tag){}
1313 for( i = 0; i< Curr_N_Conns; i++ )
1314 {
1315 if( Dns_conns[i].src_type == SRC_DIS )
1316 {
1317 n_server++;
1318 }
1319 }
1320 max_size = ((int)sizeof(DNS_SERVER_INFO) + MAX_TASK_NAME) * n_server;
1321 max_pid_size = (int)sizeof(int) * n_server;
1322 if(!curr_allocated_size)
1323 {
1324 info_buffer = (char *)malloc((size_t)max_size);
1325 curr_allocated_size = max_size;
1326 pid_buffer = (int *)malloc((size_t)max_pid_size);
1327 }
1328 else if (max_size > curr_allocated_size)
1329 {
1330 free(info_buffer);
1331 info_buffer = (char *)malloc((size_t)max_size);
1332 curr_allocated_size = max_size;
1333 free(pid_buffer);
1334 pid_buffer = (int *)malloc((size_t)max_pid_size);
1335 }
1336 info_buffer[0] = '\0';
1337 pid_buffer[0] = 0;
1338
1339 info_buffer_ptr = info_buffer;
1340 if(*first_time)
1341 {
1342 for( i = 0; i< Curr_N_Conns; i++ )
1343 {
1344 if( Dns_conns[i].src_type == SRC_DIS )
1345 {
1346 connp = &Dns_conns[i];
1347/*
1348 if((int)strlen(connp->task_name) == MAX_TASK_NAME-4-1)
1349 {
1350 strcpy(aux,connp->task_name);
1351 strcat(aux,"--CLIENT_LIST");
1352 n = find_services(aux);
1353 for(j = 0; j < n; j++)
1354 {
1355 servp = Service_info_list[j];
1356 if(i == servp->conn_id)
1357 {
1358 strcpy(aux,servp->serv_name);
1359 ptr = strstr(aux,"/CLIENT_LIST");
1360 if(ptr)
1361 *ptr = '\0';
1362 break;
1363 }
1364 }
1365 free(Service_info_list);
1366 strcpy(server, aux);
1367 }
1368 else
1369 {
1370*/
1371 strcpy(server, connp->long_task_name);
1372/*
1373 }
1374*/
1375 strcat(server,"@");
1376 strcat(server, connp->node_name);
1377 strcat(server,"|");
1378 strcpy(info_buffer_ptr, server);
1379 info_buffer_ptr += (int)strlen(server);
1380 pid_buffer[pid_index] = connp->pid;
1381 pid_index++;
1382 }
1383 }
1384 }
1385 else
1386 {
1387 connp = &Dns_conns[Last_conn_id];
1388 if(connp->n_services > 0)
1389 strcat(info_buffer, "+");
1390 else if(connp->n_services == -1)
1391 strcat(info_buffer, "!");
1392 else
1393 strcat(info_buffer, "-");
1394 strcat(info_buffer, connp->long_task_name);
1395 strcat(info_buffer,"@");
1396 strcat(info_buffer, connp->node_name);
1397 strcat(info_buffer,"|");
1398 pid_buffer[pid_index] = connp->pid;
1399 pid_index++;
1400 }
1401 info_buffer[(int)strlen(info_buffer) - 1] = '\0';
1402 info_buffer_ptr = &info_buffer[(int)strlen(info_buffer)+1];
1403 pid_size = 0;
1404 for(i = 0; i < pid_index; i++)
1405 {
1406 if(i != (pid_index -1))
1407 sprintf(server, "%d|",pid_buffer[i]);
1408 else
1409 sprintf(server, "%d",pid_buffer[i]);
1410 strcpy(info_buffer_ptr, server);
1411 info_buffer_ptr += (int)strlen(server);
1412 pid_size += (int)strlen(server);
1413 }
1414 *bufp = (int *)info_buffer;
1415 *size = (int)strlen(info_buffer)+1+pid_size+1;
1416 ENABLE_AST
1417}
1418
1419int main(int argc, char **argv)
1420{
1421 int i, protocol, dns_port;
1422 int *bufp;
1423 int size;
1424 int conn_id, id;
1425 DIS_DNS_PACKET *dis_dns_packet;
1426 char node[MAX_NAME];
1427 void service_init();
1428
1429 if(argc > 1)
1430 {
1431 if(!strcmp(argv[1],"-d"))
1432 set_debug_on();
1433 else
1434 {
1435 printf("Parameters: -d Debug On\n");
1436 exit(0);
1437 }
1438 }
1439 dim_set_write_timeout(10);
1440 dim_set_listen_backlog(1024);
1441 dim_set_keepalive_timeout(90);
1442 dim_set_write_buffer_size(32768);
1443 dim_set_read_buffer_size(32768);
1444 dim_init();
1445 conn_arr_create( SRC_DNS );
1446 service_init();
1447 Timer_q = dtq_create();
1448 get_node_name(node);
1449 dim_print_date_time();
1450 printf(" DNS version %d starting up on %s\n",DIM_VERSION_NUMBER, node);
1451 fflush(stdout);
1452
1453 Server_new_info_id =(int) dis_add_service( "DIS_DNS/SERVER_LIST", "C", 0, 0,
1454 get_new_dns_server_info, 0 );
1455 Server_info_id = (int)dis_add_service( "DIS_DNS/SERVER_INFO", 0, 0, 0,
1456 get_dns_server_info, 0 );
1457 dis_add_cmnd( "DIS_DNS/PRINT_STATS", 0, print_stats, 0 );
1458 dis_add_cmnd( "DIS_DNS/DEBUG_ON", 0, set_debug_on, 0 );
1459 dis_add_cmnd( "DIS_DNS/DEBUG_OFF", 0, set_debug_off, 0 );
1460 dis_add_cmnd( "DIS_DNS/KILL_SERVERS", "I", kill_servers, 0 );
1461 dis_add_cmnd( "DIS_DNS/PRINT_HASH_TABLE", 0, print_hash_table, 0 );
1462 dis_add_cmnd( "DIS_DNS/SERVICE_INFO/RpcIn", "C", set_rpc_info, 0 );
1463 Rpc_id = (int)dis_add_service( "DIS_DNS/SERVICE_INFO/RpcOut", "C", 0, 0,
1464 get_rpc_info, 0 );
1465 dns_port = get_dns_port_number();
1466 if( !dna_open_server(DNS_TASK, recv_rout, &protocol, &dns_port, error_handler) )
1467 return(0);
1468
1469 id = dis_start_serving("DIS_DNS");
1470 dis_dns_packet = (DIS_DNS_PACKET *) id_get_ptr(id, SRC_DIS);
1471 id_free(id, SRC_DIS);
1472 conn_id = conn_get();
1473 handle_registration(conn_id, dis_dns_packet, 0);
1474 dtq_add_entry(Timer_q, 5, update_did, 0xded0000);
1475 while(1)
1476 {
1477#ifdef VMS
1478 sys$hiber();
1479#else
1480 wake_up = FALSE;
1481 while( !wake_up )
1482 {
1483 dim_wait();
1484 }
1485#endif
1486 for( i = 0; i< Curr_N_Conns; i++ )
1487 {
1488 if( Dns_conns[i].src_type == SRC_DIS )
1489 {
1490 send_dns_server_info( i, &bufp, &size );
1491 dis_send_service( Server_info_id, bufp, size );
1492 }
1493 }
1494 }
1495 return(1);
1496}
1497
1498
1499void print_stats()
1500{
1501 int i;
1502 int n_conns = 0;
1503 int n_services = 0;
1504 int n_servers = 0;
1505 int n_clients = 0;
1506
1507 dim_print_date_time();
1508 printf(" Connection Statistics :\n");
1509 for(i = 0; i< Curr_N_Conns; i++)
1510 {
1511 switch(Dns_conns[i].src_type)
1512 {
1513 case SRC_DIS :
1514 printf("%d - Server %s@%s (PID %d) %d services\n",
1515 i, Dns_conns[i].task_name,
1516 Dns_conns[i].node_name,
1517 Dns_conns[i].pid, Dns_conns[i].n_services);
1518 fflush(stdout);
1519 n_services += Dns_conns[i].n_services;
1520 n_servers++;
1521 n_conns++;
1522 break;
1523 case SRC_DIC :
1524 printf("%d - Client %s@%s\n",
1525 i, Net_conns[i].task, Net_conns[i].node);
1526 fflush(stdout);
1527 n_conns++;
1528 n_clients++;
1529 break;
1530 default :
1531 if(Dna_conns[i].busy)
1532 {
1533 if(Net_conns[i].task[0] && Net_conns[i].node[0])
1534 printf("%d - Undefined %s@%s\n",
1535 i, Net_conns[i].task,
1536 Net_conns[i].node);
1537 else
1538 printf("%d - Undefined\n", i);
1539 fflush(stdout);
1540 n_conns++;
1541 }
1542 else
1543 {
1544 printf("%d - Empty\n", i);
1545 fflush(stdout);
1546 }
1547 }
1548 }
1549 printf("Number of Connections = %d : %d servers, %d clients\n", n_conns,
1550 n_servers, n_clients);
1551 printf("Number of Services = %d\n", n_services);
1552 fflush(stdout);
1553}
1554
1555
1556void set_debug_on()
1557{
1558 Debug = 1;
1559}
1560
1561
1562void set_debug_off()
1563{
1564 Debug = 0;
1565}
1566
1567
1568void kill_servers(int *tag, int *code, int *size)
1569{
1570 int i;
1571 DNS_DIS_PACKET dis_packet;
1572 int soft_code = 0, soft_size = 0;
1573 int type;
1574
1575 if(tag){}
1576 if(size)
1577 {
1578 soft_size = *size;
1579 if(code)
1580 {
1581 soft_code = *code;
1582 }
1583 }
1584 for(i = 0; i< Curr_N_Conns; i++)
1585 {
1586 if(Dns_conns[i].src_type == SRC_DIS)
1587 {
1588 if(!strcmp(Dns_conns[i].task_name,"DIS_DNS"))
1589 continue;
1590 fflush(stdout);
1591 type = DNS_DIS_EXIT;
1592 if(soft_size)
1593 {
1594 type = DNS_DIS_SOFT_EXIT;
1595 type |= (soft_code << (int)16) & (int)0xFFFF0000;
1596 dim_print_date_time();
1597 printf(" Killing server %s@%s with exit code %d\n",
1598 Dns_conns[i].task_name, Dns_conns[i].node_name, soft_code);
1599 }
1600 else
1601 {
1602 dim_print_date_time();
1603 printf(" Killing server %s@%s\n",
1604 Dns_conns[i].task_name, Dns_conns[i].node_name);
1605 }
1606 dis_packet.type = htovl(type);
1607 dis_packet.size = htovl(DNS_DIS_HEADER);
1608 if( !dna_write_nowait(i, &dis_packet, DNS_DIS_HEADER) )
1609 {
1610 dim_print_date_time();
1611 printf(" Kill Server: Couldn't write, releasing %d\n",i);
1612 fflush(stdout);
1613 release_conn(i);
1614 }
1615 }
1616 }
1617}
1618
1619
1620void service_init()
1621{
1622 int i;
1623
1624 for( i = 0; i < MAX_HASH_ENTRIES; i++ ) {
1625 Service_hash_table[i] = (RED_DNS_SERVICE *) malloc(sizeof(RED_DNS_SERVICE));
1626 dll_init((DLL *) Service_hash_table[i]);
1627 }
1628}
1629
1630
1631void service_insert(RED_DNS_SERVICE *servp)
1632{
1633 int index;
1634
1635 index = HashFunction(servp->serv_name, MAX_HASH_ENTRIES);
1636 dll_insert_queue((DLL *) Service_hash_table[index],
1637 (DLL *) servp);
1638}
1639
1640
1641void service_remove(RED_DNS_SERVICE *servp)
1642{
1643 if( servp->node_head )
1644 free( servp->node_head );
1645 dll_remove( (DLL *) servp );
1646}
1647
1648
1649DNS_SERVICE *service_exists(char *name)
1650{
1651 int index;
1652 RED_DNS_SERVICE *servp;
1653 char *ptr;
1654
1655 index = HashFunction(name, MAX_HASH_ENTRIES);
1656 if( (servp = (RED_DNS_SERVICE *) dll_search(
1657 (DLL *) Service_hash_table[index],
1658 name, (int)strlen(name)+1)) )
1659 {
1660 ptr = (char *)servp - (2 * sizeof(void *));
1661 return((DNS_SERVICE *)ptr);
1662 }
1663
1664 return((DNS_SERVICE *)0);
1665}
1666
1667void print_hash_table()
1668{
1669 int i;
1670 RED_DNS_SERVICE *servp;
1671 int n_entries, max_entry_index = 0;
1672 int max_entries = 0;
1673
1674#ifdef VMS
1675 if( ( foutptr = fopen( "scratch$week:[cp_operator]dim_dns.log", "w" )
1676 ) == (FILE *)0 )
1677 {
1678 printf("Cannot open: scratch$week:[cp_operator]dim_dns.log for writing\n");
1679 fflush(stdout);
1680 return;
1681 }
1682#endif
1683
1684 for( i = 0; i < MAX_HASH_ENTRIES; i++ )
1685 {
1686 n_entries = 0;
1687#ifdef VMS
1688 fprintf(foutptr,"HASH[%d] : \n",i);
1689#endif
1690 servp = Service_hash_table[i];
1691 while( (servp = (RED_DNS_SERVICE *) dll_get_next(
1692 (DLL *) Service_hash_table[i],
1693 (DLL *) servp)) )
1694 {
1695#ifdef VMS
1696 fprintf(foutptr,"%s\n",servp->serv_name);
1697#endif
1698 n_entries++;
1699 }
1700#ifdef VMS
1701 fprintf(foutptr,"\n\n");
1702#endif
1703 if(n_entries != 0)
1704 printf("HASH[%d] - %d entries\n", i, n_entries);
1705 if(n_entries > max_entries)
1706 {
1707 max_entries = n_entries;
1708 max_entry_index = i;
1709 }
1710 }
1711#ifdef VMS
1712 fclose(foutptr);
1713#endif
1714 printf("Maximum : HASH[%d] - %d entries\n", max_entry_index, max_entries);
1715 fflush(stdout);
1716}
1717
1718int find_services(char *wild_name)
1719{
1720
1721 int i;
1722 RED_DNS_SERVICE *servp;
1723 DNS_SERVICE *servp1;
1724 char tmp[MAX_NAME], *ptr, *ptr1, *dptr, *dptr1;
1725 int match, count = 0;
1726
1727 Service_info_list = (DNS_SERVICE **)
1728 malloc((size_t)(Curr_n_services*(int)sizeof(DNS_SERVICE *)));
1729
1730 if(!strchr(wild_name, '*'))
1731 {
1732 servp1 = service_exists(wild_name);
1733 if(servp1)
1734 {
1735 if(servp1->state == 1)
1736 {
1737 Service_info_list[count] = (DNS_SERVICE *)servp1;
1738 count++;
1739 return 1;
1740 }
1741 }
1742 return 0;
1743 }
1744 for( i = 0; i < MAX_HASH_ENTRIES; i++ )
1745 {
1746 servp = Service_hash_table[i];
1747 while( (servp = (RED_DNS_SERVICE *) dll_get_next(
1748 (DLL *) Service_hash_table[i],
1749 (DLL *) servp)) )
1750 {
1751 ptr = wild_name;
1752 dptr = servp->serv_name;
1753 match = 1;
1754
1755 while( (ptr1 = strchr(ptr,'*')) )
1756 {
1757 if(ptr1 == ptr)
1758 {
1759 ptr++;
1760 if(!*ptr)
1761 {
1762 dptr = ptr;
1763 break;
1764 }
1765 strcpy(tmp,ptr);
1766 if( (ptr1 = strchr(ptr,'*')) )
1767 {
1768 tmp[ptr1-ptr] = '\0';
1769 }
1770 if( (dptr1 = strstr(dptr, tmp)) )
1771 {
1772 if(!ptr1)
1773 {
1774 dptr = dptr1;
1775 break;
1776 }
1777 dptr1 += (int)strlen(tmp);
1778 ptr = ptr1;
1779 dptr = dptr1;
1780 }
1781 else
1782 {
1783 match = 0;
1784 break;
1785 }
1786 }
1787 else
1788 {
1789 strcpy(tmp,ptr);
1790 tmp[ptr1-ptr] = '\0';
1791 if(!strncmp(dptr, tmp, strlen(tmp)))
1792 {
1793 dptr += (int)strlen(tmp);
1794 ptr = ptr1;
1795 }
1796 else
1797 {
1798 match = 0;
1799 break;
1800 }
1801 }
1802 }
1803 if(strcmp(dptr, ptr))
1804 {
1805 strcpy(tmp,ptr);
1806 strcat(tmp,"/RpcIn");
1807 if(strcmp(dptr, tmp))
1808 match = 0;
1809 }
1810 if(match)
1811 {
1812 if(servp->state == 1)
1813 {
1814 ptr = (char *)servp - (2 * sizeof(void *));
1815 Service_info_list[count] = (DNS_SERVICE *)ptr;
1816 count++;
1817 }
1818 }
1819 }
1820 }
1821 return(count);
1822}
1823
1824void set_rpc_info(int *tag, char *buffer, int *size)
1825{
1826 char aux[MAX_NAME], rpcaux[MAX_NAME+32], *ptr, *rpcptr;
1827 int i, n, rpc, id[2], conn_id;
1828 DNS_SERVICE *servp, *aux_servp;
1829
1830 if(size){}
1831 if(tag){}
1832 if(Debug)
1833 {
1834 dim_print_date_time();
1835 conn_id = dis_get_conn_id();
1836 printf(" Got Browse Request <%s> from conn: %d %s@%s\n", buffer, conn_id,
1837 Net_conns[conn_id].task,Net_conns[conn_id].node);
1838 }
1839 n = find_services(buffer);
1840 if(Debug)
1841 {
1842 dim_print_date_time();
1843 conn_id = dis_get_conn_id();
1844 printf(" Browse Request <%s> found %d services\n", buffer, n);
1845 }
1846 if(!Rpc_info_size)
1847 {
1848 Rpc_info = malloc((size_t)(MAX_NAME*(n+1)*2));
1849 Rpc_info_size = MAX_NAME*(n+1)*2;
1850 }
1851 else if(Rpc_info_size < MAX_NAME*n*2)
1852 {
1853 free(Rpc_info);
1854 Rpc_info = malloc((size_t)(MAX_NAME*(n+1)*2));
1855 Rpc_info_size = MAX_NAME*(n+1)*2;
1856 }
1857 Rpc_info[0] = '\0';
1858 rpcptr = Rpc_info;
1859 for(i = 0; i < n; i++)
1860 {
1861 rpc = 0;
1862 servp = Service_info_list[i];
1863 if(strstr(servp->serv_name,"/Rpc"))
1864 {
1865 strcpy(aux,servp->serv_name);
1866 if( (ptr = strstr(aux,"/RpcIn")) )
1867 {
1868 *ptr = '\0';
1869 rpc = 1;
1870 if( (ptr = strstr(Rpc_info, aux)) )
1871 {
1872 ptr += (int)strlen(aux);
1873 if(*ptr == '|')
1874 rpc = 2;
1875 }
1876 }
1877 if( (ptr = strstr(aux,"/RpcOut")) )
1878 {
1879 *ptr = '\0';
1880 rpc = 1;
1881 if( (ptr = strstr(Rpc_info, aux)) )
1882 {
1883 ptr += (int)strlen(aux);
1884 if(*ptr == '|')
1885 rpc = 2;
1886 }
1887 }
1888 if(rpc == 1)
1889 {
1890 strcpy(rpcaux, aux);
1891 strcat(rpcaux,"|");
1892 strcat(aux,"/RpcIn");
1893 if( (aux_servp = service_exists(aux)) )
1894 {
1895 strcat(rpcaux, aux_servp->serv_def);
1896 strcat(rpcaux,",");
1897 ptr = strstr(aux,"/RpcIn");
1898 *ptr = '\0';
1899 strcat(aux,"/RpcOut");
1900 if( (aux_servp = service_exists(aux)) )
1901 {
1902 strcat(rpcaux,aux_servp->serv_def);
1903 strcat(rpcaux,"|RPC\n");
1904 strcpy(rpcptr, rpcaux);
1905 rpcptr += (int)strlen(rpcaux);
1906 }
1907 }
1908 }
1909 }
1910 else
1911 {
1912 strcpy(rpcaux, servp->serv_name);
1913 strcat(rpcaux,"|");
1914 strcat(rpcaux,servp->serv_def);
1915 if(servp->serv_id & 0x10000000)
1916 strcat(rpcaux,"|CMD\n");
1917 else
1918 strcat(rpcaux,"|\n");
1919 strcpy(rpcptr, rpcaux);
1920 rpcptr += (int)strlen(rpcaux);
1921 }
1922 }
1923 *rpcptr = '\0';
1924 id[0] = dis_get_conn_id();
1925 id[1] = 0;
1926 dis_selective_update_service(Rpc_id, id);
1927 free(Service_info_list);
1928}
1929
1930void get_rpc_info(int *tag, char **buffer, int *size)
1931{
1932
1933 if(tag){}
1934 *buffer = Rpc_info;
1935 *size = (int)strlen(Rpc_info)+1;
1936}
1937
Note: See TracBrowser for help on using the repository browser.