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

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