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

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