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

Last change on this file since 13452 was 13135, checked in by tbretz, 13 years ago
Updated to v19r30
File size: 44.0 KB
Line 
1/*
2 * DNS (Delphi Name Server) Package implements the name server for the DIM
3 * (Delphi Information Management) system
4 *
5 * Started date : 26-10-92
6 * Last modification : 02-08-94
7 * Written by : C. Gaspar
8 * Adjusted by : G.C. Ballintijn
9 *
10 */
11
12#define DNS
13#include <stdio.h>
14#include <dim.h>
15#include <dis.h>
16
17#ifndef WIN32
18#include <netdb.h>
19#endif
20/*
21#define MAX_HASH_ENTRIES 5000
22*/
23#define MAX_HASH_ENTRIES 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, dim_get_keepalive_timeout());
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, dim_get_keepalive_timeout());
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 else
653 Dns_conns[conn_id].validity = -Dns_conns[conn_id].validity;
654 }
655}
656
657
658int handle_client_request( int conn_id, DIC_DNS_PACKET *packet )
659{
660 DNS_SERVICE *servp;
661 NODE *nodep;
662 RED_NODE *red_nodep;
663 int i, service_id;
664 DNS_DIC_PACKET dic_packet;
665 SERVICE_REG *serv_regp;
666 void service_insert();
667 void service_remove();
668 void tcpip_get_addresses();
669 char *ptr, *ptr1;
670 int found;
671
672 serv_regp = (SERVICE_REG *)(&(packet->service));
673 if(Debug)
674 {
675 dim_print_date_time();
676 printf(" Conn %3d : Client %s@%s requested %s\n",
677 conn_id, Net_conns[conn_id].task, Net_conns[conn_id].node,
678 serv_regp->service_name);
679 fflush(stdout);
680 }
681
682 if(DNS_accepted_nodes[0] == 0)
683 {
684 if(!get_dns_accepted_nodes(DNS_accepted_nodes))
685 DNS_accepted_nodes[0] = -1;
686 }
687 if(DNS_accepted_nodes[0] != -1)
688 {
689 ptr = DNS_accepted_nodes;
690 found = 0;
691 while(*ptr)
692 {
693 ptr1 = strchr(ptr,',');
694 if(ptr1)
695 {
696 *ptr1 = '\0';
697 ptr1++;
698 }
699 else
700 {
701 ptr1 = ptr;
702 ptr1 += strlen(ptr);
703 }
704 if(strstr(Net_conns[conn_id].node,ptr))
705 {
706 found = 1;
707 break;
708 }
709 ptr = ptr1;
710 }
711 if(!found)
712 {
713 dic_packet.service_id = serv_regp->service_id;
714 dic_packet.node_name[0] = -1;
715 dic_packet.task_name[0] = 0;
716 dic_packet.node_addr[0] = 0;
717 dic_packet.pid = 0;
718 dic_packet.size = htovl(DNS_DIC_HEADER);
719 dim_print_date_time();
720 printf(" Connection from %s refused, stopping client pid=%s\n",
721 Net_conns[conn_id].node,
722 Net_conns[conn_id].task);
723 fflush(stdout);
724 if( !dna_write_nowait(conn_id, &dic_packet, DNS_DIC_HEADER) )
725 {
726 dim_print_date_time();
727 printf(" Stop Client: Couldn't write, releasing Conn %3d : Client %s@%s\n",conn_id,
728 Net_conns[conn_id].task,
729 Net_conns[conn_id].node);
730 fflush(stdout);
731 }
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( Dns_conns[conn_id].src_type == SRC_NONE )
829 dna_set_test_write(conn_id, dim_get_keepalive_timeout());
830 if( !(servp = service_exists(serv_regp->service_name)) )
831 {
832 if(Debug)
833 {
834 printf("\tService does not exist, queueing request\n");
835 fflush(stdout);
836 }
837 if( !Dns_conns[conn_id].node_head )
838 {
839 Dns_conns[conn_id].src_type = SRC_DIC;
840 Dns_conns[conn_id].node_head =
841 malloc(sizeof(NODE));
842 dll_init( (DLL *) Dns_conns[conn_id].node_head );
843 }
844 servp = (DNS_SERVICE *) malloc(sizeof(DNS_SERVICE));
845 strncpy( servp->serv_name, serv_regp->service_name, MAX_NAME );
846 servp->serv_def[0] = '\0';
847 servp->state = 0;
848 servp->conn_id = 0;
849 service_insert(&(servp->next));
850 Curr_n_services++;
851 servp->node_head = (RED_NODE *)malloc(sizeof(NODE));
852 dll_init( (DLL *) servp->node_head );
853 nodep = (NODE *)malloc(sizeof(NODE));
854 nodep->conn_id = conn_id;
855 nodep->service_id = service_id;
856 nodep->servp = servp;
857 dll_insert_queue((DLL *) Dns_conns[conn_id].node_head,
858 (DLL *) nodep);
859 dll_insert_queue((DLL *) servp->node_head,
860 (DLL *) &(nodep->next));
861 }
862 else
863 {
864 if( servp->state == 1 )
865 {
866#ifdef VMS
867 if(servp->server_format & MY_OS9)
868 {
869 dna_test_write(servp->conn_id);
870 }
871#endif
872 Dns_conns[conn_id].src_type = SRC_DIC;
873 strcpy( dic_packet.node_name,
874 Dns_conns[servp->conn_id].node_name );
875 strcpy( dic_packet.task_name,
876 Dns_conns[servp->conn_id].task_name );
877 for(i = 0; i < 4; i++)
878 dic_packet.node_addr[i] =
879 Dns_conns[servp->conn_id].node_addr[i];
880 dic_packet.port = htovl(Dns_conns[servp->conn_id].port);
881 dic_packet.pid = htovl(Dns_conns[servp->conn_id].pid);
882 dic_packet.protocol = htovl(Dns_conns[servp->conn_id].protocol);
883 dic_packet.format = htovl(servp->server_format);
884 strcpy( dic_packet.service_def, servp->serv_def );
885 if(Debug)
886 {
887 printf("\tService exists in %s@%s, port = %d\n",
888 dic_packet.task_name, dic_packet.node_name,
889 dic_packet.port);
890 fflush(stdout);
891 }
892 }
893 else
894 {
895 if(Debug)
896 {
897 if(servp->state == -1)
898 {
899 printf("\tService exists in BAD state, queueing request\n");
900 fflush(stdout);
901 }
902 else
903 {
904 printf("\tService does not exist (other client(s) waiting), queueing request\n");
905 fflush(stdout);
906 }
907 }
908 if(!(NODE *)Dns_conns[conn_id].node_head )
909 {
910 Dns_conns[conn_id].src_type = SRC_DIC;
911 Dns_conns[conn_id].node_head =
912 (char *) malloc(sizeof(NODE));
913 dll_init((DLL *)Dns_conns[conn_id].node_head);
914 }
915 nodep = (NODE *)malloc(sizeof(NODE));
916 nodep->conn_id = conn_id;
917 nodep->service_id = service_id;
918 nodep->servp = servp;
919 dll_insert_queue((DLL *) Dns_conns[conn_id].node_head,
920 (DLL *) nodep);
921 dll_insert_queue((DLL *) servp->node_head,
922 (DLL *) &(nodep->next));
923 }
924 }
925/* Should it be dna_write_nowait? 16/9/2008 */
926/* moved from dna_write to dna_write_nowait in 14/10/2008 */
927 if( !dna_write_nowait(conn_id, &dic_packet, DNS_DIC_HEADER) )
928 {
929 dim_print_date_time();
930 printf(" Client Request: Couldn't write, releasing Conn %3d : Client %s@%s\n",conn_id,
931 Net_conns[conn_id].task,
932 Net_conns[conn_id].node);
933 fflush(stdout);
934 release_conn(conn_id);
935 }
936
937 return(1);
938}
939
940void do_inform_clients(int conn_id)
941{
942 DNS_SERVICE *servp;
943 int n_informed = 0;
944 static DNS_SERVICE *prev_servp = (DNS_SERVICE *)0;
945 static int n_times = 0;
946 void inform_clients();
947
948 DISABLE_AST
949 if(!Dns_conns[conn_id].service_head)
950 {
951 prev_servp = (DNS_SERVICE *)0;
952 ENABLE_AST
953 return;
954 }
955 if(prev_servp)
956 servp = prev_servp;
957 else
958 servp = (DNS_SERVICE *)Dns_conns[conn_id].service_head;
959 while( (servp = (DNS_SERVICE *) dll_get_next(
960 (DLL *) Dns_conns[conn_id].service_head,
961 (DLL *) servp)) )
962 {
963 if( servp->state != -1 )
964 {
965 if( !dll_empty((DLL *) servp->node_head))
966 {
967 inform_clients(servp);
968 n_informed++;
969 if(n_informed == 1000)
970 {
971 dtq_start_timer(0, do_inform_clients, conn_id);
972 ENABLE_AST
973 return;
974 }
975 }
976 }
977 }
978 n_times = 0;
979 prev_servp = (DNS_SERVICE *)0;
980 ENABLE_AST
981}
982
983
984void inform_clients(DNS_SERVICE *servp)
985{
986 RED_NODE *nodep, *prevp;
987 NODE *full_nodep;
988 DNS_DIC_PACKET packet;
989 char *ptr;
990 int i, to_release = 0;
991
992 nodep = servp->node_head;
993 prevp = nodep;
994 while( (nodep = (RED_NODE *) dll_get_next((DLL *) servp->node_head,
995 (DLL *) prevp)) )
996 {
997 packet.service_id = htovl(nodep->service_id);
998 strcpy(packet.node_name, Dns_conns[servp->conn_id].node_name);
999 strcpy(packet.task_name, Dns_conns[servp->conn_id].task_name);
1000 for(i = 0; i < 4; i++)
1001 packet.node_addr[i] = Dns_conns[servp->conn_id].node_addr[i];
1002 packet.port = htovl(Dns_conns[servp->conn_id].port);
1003 packet.pid = htovl(Dns_conns[servp->conn_id].pid);
1004 packet.protocol = htovl(Dns_conns[servp->conn_id].protocol);
1005 packet.size = htovl(DNS_DIC_HEADER);
1006 packet.format = htovl(servp->server_format);
1007 strcpy( packet.service_def, servp->serv_def );
1008/* Should it be dna_write_nowait? 16/9/2008 */
1009/* moved from dna_write to dna_write_nowait in 14/10/2008 */
1010/*
1011 dna_write_nowait(nodep->conn_id, &packet, DNS_DIC_HEADER);
1012*/
1013 if( !dna_write_nowait(nodep->conn_id, &packet, DNS_DIC_HEADER) )
1014 {
1015 dim_print_date_time();
1016 printf(" Inform Client: Couldn't write, releasing Conn %3d : Client %s@%s\n",nodep->conn_id,
1017 Net_conns[nodep->conn_id].task,
1018 Net_conns[nodep->conn_id].node);
1019 fflush(stdout);
1020 to_release = nodep->conn_id;
1021/*
1022release_conn(nodep->conn_id);
1023*/
1024 }
1025/*
1026 if(dna_write_nowait(nodep->conn_id, &packet, DNS_DIC_HEADER))
1027 {
1028*/
1029 dll_remove( (DLL *) nodep );
1030 ptr = (char *)nodep - (2 * sizeof(void *));
1031 full_nodep = (NODE *)ptr;
1032 dll_remove( (DLL *) full_nodep );
1033 nodep = nodep->prev;
1034 free( full_nodep );
1035 prevp = nodep;
1036/*
1037 }
1038*/
1039 }
1040 if(to_release)
1041 release_conn(to_release);
1042}
1043
1044#ifdef VMS
1045static release_client(int conn_id)
1046{
1047char *ptr_task;
1048char *ptr_node;
1049int i;
1050
1051 ptr_task = Net_conns[conn_id].task;
1052 ptr_node = Net_conns[conn_id].node;
1053 for( i = 0; i< Curr_N_Conns; i++ )
1054 {
1055 if( (!strcmp(Net_conns[i].task,ptr_task)) &&
1056 (!strcmp(Net_conns[i].node,ptr_node)) )
1057 {
1058 if(i != conn_id)
1059 {
1060 if( Dns_conns[i].src_type == SRC_DIC )
1061 {
1062 if(Debug)
1063 {
1064 dim_print_date_time();
1065 printf(" Releasing client on conn %d - %s@%s\n",
1066 i, Net_conns[i].task, Net_conns[i].node);
1067 fflush(stdout);
1068 }
1069 release_conn(i);
1070 }
1071 }
1072 }
1073 }
1074}
1075#endif
1076
1077static void release_conn(int conn_id)
1078{
1079 DNS_SERVICE *servp, *old_servp;
1080 NODE *nodep, *old_nodep;
1081 DNS_CONNECTION *connp;
1082 void service_remove();
1083
1084 connp = &Dns_conns[conn_id];
1085 if( Dns_conns[conn_id].src_type == SRC_DIS )
1086 {
1087 if( Debug )
1088 {
1089 dim_print_date_time();
1090 printf( " Conn %3d : Server %s@%s died\n",
1091 conn_id, Dns_conns[conn_id].task_name,
1092 Dns_conns[conn_id].node_name);
1093 fflush(stdout);
1094 }
1095 else
1096 {
1097 if(Dns_conns[conn_id].n_services == -1)
1098 {
1099 dim_print_date_time();
1100 printf( " Conn %3d : Server %s@%s died\n",
1101 conn_id, Dns_conns[conn_id].task_name,
1102 Dns_conns[conn_id].node_name);
1103 fflush(stdout);
1104 }
1105 }
1106 Curr_n_servers--;
1107 if( Dns_conns[conn_id].timr_ent )
1108 {
1109 dtq_rem_entry( Timer_q, Dns_conns[conn_id].timr_ent );
1110 Dns_conns[conn_id].timr_ent = NULL;
1111 }
1112 servp = (DNS_SERVICE *)Dns_conns[conn_id].service_head;
1113 while( (servp = (DNS_SERVICE *) dll_get_next(
1114 (DLL *) Dns_conns[conn_id].service_head,
1115 (DLL *) servp)) )
1116 {
1117 dll_remove((DLL *) servp);
1118 if(dll_empty((DLL *) servp->node_head))
1119 {
1120 service_remove(&(servp->next));
1121 Curr_n_services--;
1122 old_servp = servp;
1123 servp = servp->server_prev;
1124 free(old_servp);
1125 }
1126 else
1127 {
1128 servp->state = 0;
1129 servp->conn_id = 0;
1130 servp = servp->server_prev;
1131 }
1132 }
1133 if(Dns_conns[conn_id].n_services)
1134 {
1135 Dns_conns[conn_id].n_services = 0;
1136
1137 do_update_did(conn_id);
1138/*
1139 Last_conn_id = conn_id;
1140 dis_update_service(Server_new_info_id);
1141 dis_update_service(Server_info_id);
1142*/
1143 }
1144 free((DNS_SERVICE *)Dns_conns[conn_id].service_head);
1145 Dns_conns[conn_id].service_head = 0;
1146 Dns_conns[conn_id].src_type = SRC_NONE;
1147 dna_close(conn_id);
1148 }
1149 else if(Dns_conns[conn_id].src_type == SRC_DIC)
1150 {
1151 if(Debug)
1152 {
1153 dim_print_date_time();
1154 printf(" Conn %3d : Client %s@%s died\n",
1155 conn_id, Net_conns[conn_id].task, Net_conns[conn_id].node);
1156 fflush(stdout);
1157 }
1158 if( (nodep = (NODE *)Dns_conns[conn_id].node_head) )
1159 {
1160 while( (nodep = (NODE *) dll_get_next(
1161 (DLL *) Dns_conns[conn_id].node_head,
1162 (DLL *) nodep)) )
1163 {
1164 servp = nodep->servp;
1165 dll_remove( (DLL *) nodep );
1166 dll_remove( (DLL *) &(nodep->next) );
1167 old_nodep = nodep;
1168 nodep = nodep->client_prev;
1169 free(old_nodep);
1170 if( (dll_empty((DLL *) servp->node_head)) &&
1171 (!servp->conn_id) )
1172 {
1173 service_remove(&(servp->next));
1174 Curr_n_services--;
1175 free( servp );
1176 }
1177 }
1178 free(Dns_conns[conn_id].node_head);
1179 Dns_conns[conn_id].node_head = 0;
1180 }
1181 Dns_conns[conn_id].src_type = SRC_NONE;
1182 dna_close(conn_id);
1183 }
1184 else
1185 {
1186 if(Debug)
1187 {
1188 dim_print_date_time();
1189 printf(" Conn %3d : Undefined Type %s@%s died\n",
1190 conn_id, Net_conns[conn_id].task,
1191 Net_conns[conn_id].node);
1192 fflush(stdout);
1193 }
1194 dna_close(conn_id);
1195 }
1196}
1197
1198
1199void set_in_error(int conn_id)
1200{
1201 DNS_SERVICE *servp;
1202
1203 if(Dns_conns[conn_id].src_type == SRC_DIS)
1204 {
1205 if(strcmp(Dns_conns[conn_id].task_name,"DIS_DNS"))
1206 dna_rem_test_write(conn_id);
1207 servp = (DNS_SERVICE *)Dns_conns[conn_id].service_head;
1208 while( (servp = (DNS_SERVICE *) dll_get_next(
1209 (DLL *) Dns_conns[conn_id].service_head,
1210 (DLL *) servp)) )
1211 servp->state = -1;
1212 Dns_conns[conn_id].n_services = -1;
1213 }
1214}
1215
1216void get_dns_server_info(int *tag, int **bufp, int *size, int *first_time)
1217{
1218 if(tag){}
1219 if(*first_time)
1220 {
1221
1222#ifdef VMS
1223 sys$wake(0, 0);
1224#else
1225 wake_up = TRUE;
1226#ifdef WIN32
1227 wake_up();
1228#endif
1229#endif
1230 *size = 0;
1231 }
1232 else
1233 {
1234 send_dns_server_info(Last_conn_id, bufp, size);
1235 }
1236}
1237
1238
1239void send_dns_server_info(int conn_id, int **bufp, int *size)
1240{
1241 static int curr_allocated_size = 0;
1242 static DNS_DID *dns_info_buffer;
1243 DNS_SERVICE *servp;
1244 DNS_SERVER_INFO *dns_server_info;
1245 DNS_SERVICE_INFO *dns_service_info;
1246 DNS_CONNECTION *connp;
1247 int max_size;
1248 int n_services;
1249
1250 DISABLE_AST
1251 connp = &Dns_conns[conn_id];
1252 if(connp->src_type != SRC_DIS)
1253 {
1254 ENABLE_AST
1255 return;
1256 }
1257 n_services = connp->n_services;
1258 if(n_services == -1)
1259 n_services = 0;
1260 max_size = sizeof(DNS_SERVER_INFO) +
1261 n_services * sizeof(DNS_SERVICE_INFO);
1262 if(!curr_allocated_size)
1263 {
1264 dns_info_buffer = (DNS_DID *)malloc(max_size);
1265 curr_allocated_size = max_size;
1266 }
1267 else if (max_size > curr_allocated_size)
1268 {
1269 free(dns_info_buffer);
1270 dns_info_buffer = (DNS_DID *)malloc(max_size);
1271 curr_allocated_size = max_size;
1272 }
1273 dns_server_info = &dns_info_buffer->server;
1274 dns_service_info = dns_info_buffer->services;
1275 strncpy(dns_server_info->task, connp->task_name, MAX_TASK_NAME-4);
1276 strncpy(dns_server_info->node, connp->node_name, MAX_NODE_NAME);
1277 dns_server_info->pid = htovl(connp->pid);
1278 dns_server_info->n_services = htovl(connp->n_services);
1279 servp = (DNS_SERVICE *)connp->service_head;
1280 while( (servp = (DNS_SERVICE *) dll_get_next((DLL *) connp->service_head,
1281 (DLL *) servp)) )
1282 {
1283 strncpy(dns_service_info->name, servp->serv_name, MAX_NAME);
1284 dns_service_info->status = htovl(1);
1285 if(servp->serv_id & 0x10000000)
1286 dns_service_info->type = htovl(1);
1287 else
1288 dns_service_info->type = htovl(0);
1289 dns_service_info++;
1290 }
1291 *bufp = (int *)dns_info_buffer;
1292 *size = max_size;
1293 ENABLE_AST
1294}
1295
1296void get_new_dns_server_info(int *tag, int **bufp, int *size, int *first_time)
1297{
1298 static int curr_allocated_size = 0;
1299 static char *info_buffer;
1300 static int *pid_buffer, pid_size;
1301 int pid_index = 0;
1302 DNS_CONNECTION *connp;
1303 int i, max_size, max_pid_size/*, j, n*/;
1304 int n_server = 0;
1305 char /*aux[MAX_NAME], *ptr, */ server[MAX_NAME], *info_buffer_ptr;
1306/*
1307 DNS_SERVICE *servp;
1308 int find_services();
1309*/
1310
1311 DISABLE_AST
1312 if(tag){}
1313 for( i = 0; i< Curr_N_Conns; i++ )
1314 {
1315 if( Dns_conns[i].src_type == SRC_DIS )
1316 {
1317 n_server++;
1318 }
1319 }
1320 max_size = (sizeof(DNS_SERVER_INFO) + MAX_TASK_NAME) * n_server;
1321 max_pid_size = sizeof(int) * n_server;
1322 if(!curr_allocated_size)
1323 {
1324 info_buffer = (char *)malloc(max_size);
1325 curr_allocated_size = max_size;
1326 pid_buffer = (int *)malloc(max_pid_size);
1327 }
1328 else if (max_size > curr_allocated_size)
1329 {
1330 free(info_buffer);
1331 info_buffer = (char *)malloc(max_size);
1332 curr_allocated_size = max_size;
1333 free(pid_buffer);
1334 pid_buffer = (int *)malloc(max_pid_size);
1335 }
1336 info_buffer[0] = '\0';
1337 pid_buffer[0] = 0;
1338
1339 info_buffer_ptr = info_buffer;
1340 if(*first_time)
1341 {
1342 for( i = 0; i< Curr_N_Conns; i++ )
1343 {
1344 if( Dns_conns[i].src_type == SRC_DIS )
1345 {
1346 connp = &Dns_conns[i];
1347/*
1348 if(strlen(connp->task_name) == MAX_TASK_NAME-4-1)
1349 {
1350 strcpy(aux,connp->task_name);
1351 strcat(aux,"--CLIENT_LIST");
1352 n = find_services(aux);
1353 for(j = 0; j < n; j++)
1354 {
1355 servp = Service_info_list[j];
1356 if(i == servp->conn_id)
1357 {
1358 strcpy(aux,servp->serv_name);
1359 ptr = strstr(aux,"/CLIENT_LIST");
1360 if(ptr)
1361 *ptr = '\0';
1362 break;
1363 }
1364 }
1365 free(Service_info_list);
1366 strcpy(server, aux);
1367 }
1368 else
1369 {
1370*/
1371 strcpy(server, connp->long_task_name);
1372/*
1373 }
1374*/
1375 strcat(server,"@");
1376 strcat(server, connp->node_name);
1377 strcat(server,"|");
1378 strcpy(info_buffer_ptr, server);
1379 info_buffer_ptr += strlen(server);
1380 pid_buffer[pid_index] = connp->pid;
1381 pid_index++;
1382 }
1383 }
1384 }
1385 else
1386 {
1387 connp = &Dns_conns[Last_conn_id];
1388 if(connp->n_services > 0)
1389 strcat(info_buffer, "+");
1390 else if(connp->n_services == -1)
1391 strcat(info_buffer, "!");
1392 else
1393 strcat(info_buffer, "-");
1394 strcat(info_buffer, connp->long_task_name);
1395 strcat(info_buffer,"@");
1396 strcat(info_buffer, connp->node_name);
1397 strcat(info_buffer,"|");
1398 pid_buffer[pid_index] = connp->pid;
1399 pid_index++;
1400 }
1401 info_buffer[strlen(info_buffer) - 1] = '\0';
1402 info_buffer_ptr = &info_buffer[strlen(info_buffer)+1];
1403 pid_size = 0;
1404 for(i = 0; i < pid_index; i++)
1405 {
1406 if(i != (pid_index -1))
1407 sprintf(server, "%d|",pid_buffer[i]);
1408 else
1409 sprintf(server, "%d",pid_buffer[i]);
1410 strcpy(info_buffer_ptr, server);
1411 info_buffer_ptr += strlen(server);
1412 pid_size += strlen(server);
1413 }
1414 *bufp = (int *)info_buffer;
1415 *size = strlen(info_buffer)+1+pid_size+1;
1416 ENABLE_AST
1417}
1418
1419int main(int argc, char **argv)
1420{
1421 int i, protocol, dns_port;
1422 int *bufp;
1423 int size;
1424 int conn_id, id;
1425 DIS_DNS_PACKET *dis_dns_packet;
1426 char node[MAX_NAME];
1427 void service_init();
1428
1429 if(argc > 1)
1430 {
1431 if(!strcmp(argv[1],"-d"))
1432 set_debug_on();
1433 else
1434 {
1435 printf("Parameters: -d Debug On\n");
1436 exit(0);
1437 }
1438 }
1439 dim_set_write_timeout(10);
1440 dim_set_listen_backlog(1024);
1441 dim_init();
1442 conn_arr_create( SRC_DNS );
1443 service_init();
1444 Timer_q = dtq_create();
1445 get_node_name(node);
1446 dim_print_date_time();
1447 printf(" DNS version %d starting up on %s\n",DIM_VERSION_NUMBER, node);
1448 fflush(stdout);
1449
1450 Server_new_info_id = dis_add_service( "DIS_DNS/SERVER_LIST", "C", 0, 0,
1451 get_new_dns_server_info, 0 );
1452 Server_info_id = dis_add_service( "DIS_DNS/SERVER_INFO", 0, 0, 0,
1453 get_dns_server_info, 0 );
1454 dis_add_cmnd( "DIS_DNS/PRINT_STATS", 0, print_stats, 0 );
1455 dis_add_cmnd( "DIS_DNS/DEBUG_ON", 0, set_debug_on, 0 );
1456 dis_add_cmnd( "DIS_DNS/DEBUG_OFF", 0, set_debug_off, 0 );
1457 dis_add_cmnd( "DIS_DNS/KILL_SERVERS", 0, kill_servers, 0 );
1458 dis_add_cmnd( "DIS_DNS/PRINT_HASH_TABLE", 0, print_hash_table, 0 );
1459 dis_add_cmnd( "DIS_DNS/SERVICE_INFO/RpcIn", "C", set_rpc_info, 0 );
1460 Rpc_id = dis_add_service( "DIS_DNS/SERVICE_INFO/RpcOut", "C", 0, 0,
1461 get_rpc_info, 0 );
1462 dns_port = get_dns_port_number();
1463 if( !dna_open_server(DNS_TASK, recv_rout, &protocol, &dns_port, error_handler) )
1464 return(0);
1465
1466 id = dis_start_serving("DIS_DNS");
1467 dis_dns_packet = (DIS_DNS_PACKET *) id_get_ptr(id, SRC_DIS);
1468 id_free(id, SRC_DIS);
1469 conn_id = conn_get();
1470 handle_registration(conn_id, dis_dns_packet, 0);
1471 dtq_add_entry(Timer_q, 5, update_did, 0xded0000);
1472 while(1)
1473 {
1474#ifdef VMS
1475 sys$hiber();
1476#else
1477 wake_up = FALSE;
1478 while( !wake_up )
1479 {
1480 dim_wait();
1481 }
1482#endif
1483 for( i = 0; i< Curr_N_Conns; i++ )
1484 {
1485 if( Dns_conns[i].src_type == SRC_DIS )
1486 {
1487 send_dns_server_info( i, &bufp, &size );
1488 dis_send_service( Server_info_id, bufp, size );
1489 }
1490 }
1491 }
1492 return(1);
1493}
1494
1495
1496void print_stats()
1497{
1498 int i;
1499 int n_conns = 0;
1500 int n_services = 0;
1501 int n_servers = 0;
1502 int n_clients = 0;
1503
1504 dim_print_date_time();
1505 printf(" Connection Statistics :\n");
1506 for(i = 0; i< Curr_N_Conns; i++)
1507 {
1508 switch(Dns_conns[i].src_type)
1509 {
1510 case SRC_DIS :
1511 printf("%d - Server %s@%s (PID %d) %d services\n",
1512 i, Dns_conns[i].task_name,
1513 Dns_conns[i].node_name,
1514 Dns_conns[i].pid, Dns_conns[i].n_services);
1515 fflush(stdout);
1516 n_services += Dns_conns[i].n_services;
1517 n_servers++;
1518 n_conns++;
1519 break;
1520 case SRC_DIC :
1521 printf("%d - Client %s@%s\n",
1522 i, Net_conns[i].task, Net_conns[i].node);
1523 fflush(stdout);
1524 n_conns++;
1525 n_clients++;
1526 break;
1527 default :
1528 if(Dna_conns[i].busy)
1529 {
1530 if(Net_conns[i].task[0] && Net_conns[i].node[0])
1531 printf("%d - Undefined %s@%s\n",
1532 i, Net_conns[i].task,
1533 Net_conns[i].node);
1534 else
1535 printf("%d - Undefined\n", i);
1536 fflush(stdout);
1537 n_conns++;
1538 }
1539 else
1540 {
1541 printf("%d - Empty\n", i);
1542 fflush(stdout);
1543 }
1544 }
1545 }
1546 printf("Number of Connections = %d : %d servers, %d clients\n", n_conns,
1547 n_servers, n_clients);
1548 printf("Number of Services = %d\n", n_services);
1549 fflush(stdout);
1550}
1551
1552
1553void set_debug_on()
1554{
1555 Debug = 1;
1556}
1557
1558
1559void set_debug_off()
1560{
1561 Debug = 0;
1562}
1563
1564
1565void kill_servers()
1566{
1567 int i;
1568 DNS_DIS_PACKET dis_packet;
1569
1570 for(i = 0; i< Curr_N_Conns; i++)
1571 {
1572 if(Dns_conns[i].src_type == SRC_DIS)
1573 {
1574 if(!strcmp(Dns_conns[i].task_name,"DIS_DNS"))
1575 continue;
1576 dim_print_date_time();
1577 printf(" Killing server %s@%s\n",
1578 Dns_conns[i].task_name, Dns_conns[i].node_name);
1579 fflush(stdout);
1580 dis_packet.type = htovl(DNS_DIS_EXIT);
1581 dis_packet.size = htovl(DNS_DIS_HEADER);
1582 if( !dna_write_nowait(i, &dis_packet, DNS_DIS_HEADER) )
1583 {
1584 dim_print_date_time();
1585 printf(" Kill Server: Couldn't write, releasing %d\n",i);
1586 fflush(stdout);
1587 release_conn(i);
1588 }
1589 }
1590 }
1591}
1592
1593
1594void service_init()
1595{
1596 int i;
1597
1598 for( i = 0; i < MAX_HASH_ENTRIES; i++ ) {
1599 Service_hash_table[i] = (RED_DNS_SERVICE *) malloc(sizeof(RED_DNS_SERVICE));
1600 dll_init((DLL *) Service_hash_table[i]);
1601 }
1602}
1603
1604
1605void service_insert(RED_DNS_SERVICE *servp)
1606{
1607 int index;
1608
1609 index = HashFunction(servp->serv_name, MAX_HASH_ENTRIES);
1610 dll_insert_queue((DLL *) Service_hash_table[index],
1611 (DLL *) servp);
1612}
1613
1614
1615void service_remove(RED_DNS_SERVICE *servp)
1616{
1617 if( servp->node_head )
1618 free( servp->node_head );
1619 dll_remove( (DLL *) servp );
1620}
1621
1622
1623DNS_SERVICE *service_exists(char *name)
1624{
1625 int index;
1626 RED_DNS_SERVICE *servp;
1627 char *ptr;
1628
1629 index = HashFunction(name, MAX_HASH_ENTRIES);
1630 if( (servp = (RED_DNS_SERVICE *) dll_search(
1631 (DLL *) Service_hash_table[index],
1632 name, strlen(name)+1)) )
1633 {
1634 ptr = (char *)servp - (2 * sizeof(void *));
1635 return((DNS_SERVICE *)ptr);
1636 }
1637
1638 return((DNS_SERVICE *)0);
1639}
1640
1641void print_hash_table()
1642{
1643 int i;
1644 RED_DNS_SERVICE *servp;
1645 int n_entries, max_entry_index = 0;
1646 int max_entries = 0;
1647
1648#ifdef VMS
1649 if( ( foutptr = fopen( "scratch$week:[cp_operator]dim_dns.log", "w" )
1650 ) == (FILE *)0 )
1651 {
1652 printf("Cannot open: scratch$week:[cp_operator]dim_dns.log for writing\n");
1653 fflush(stdout);
1654 return;
1655 }
1656#endif
1657
1658 for( i = 0; i < MAX_HASH_ENTRIES; i++ )
1659 {
1660 n_entries = 0;
1661#ifdef VMS
1662 fprintf(foutptr,"HASH[%d] : \n",i);
1663#endif
1664 servp = Service_hash_table[i];
1665 while( (servp = (RED_DNS_SERVICE *) dll_get_next(
1666 (DLL *) Service_hash_table[i],
1667 (DLL *) servp)) )
1668 {
1669#ifdef VMS
1670 fprintf(foutptr,"%s\n",servp->serv_name);
1671#endif
1672 n_entries++;
1673 }
1674#ifdef VMS
1675 fprintf(foutptr,"\n\n");
1676#endif
1677 if(n_entries != 0)
1678 printf("HASH[%d] - %d entries\n", i, n_entries);
1679 if(n_entries > max_entries)
1680 {
1681 max_entries = n_entries;
1682 max_entry_index = i;
1683 }
1684 }
1685#ifdef VMS
1686 fclose(foutptr);
1687#endif
1688 printf("Maximum : HASH[%d] - %d entries\n", max_entry_index, max_entries);
1689 fflush(stdout);
1690}
1691
1692int find_services(char *wild_name)
1693{
1694
1695 int i;
1696 RED_DNS_SERVICE *servp;
1697 DNS_SERVICE *servp1;
1698 char tmp[MAX_NAME], *ptr, *ptr1, *dptr, *dptr1;
1699 int match, count = 0;
1700
1701 Service_info_list = (DNS_SERVICE **)
1702 malloc(Curr_n_services*sizeof(DNS_SERVICE *));
1703
1704 if(!strchr(wild_name, '*'))
1705 {
1706 servp1 = service_exists(wild_name);
1707 if(servp1)
1708 {
1709 if(servp1->state == 1)
1710 {
1711 Service_info_list[count] = (DNS_SERVICE *)servp1;
1712 count++;
1713 return 1;
1714 }
1715 }
1716 return 0;
1717 }
1718 for( i = 0; i < MAX_HASH_ENTRIES; i++ )
1719 {
1720 servp = Service_hash_table[i];
1721 while( (servp = (RED_DNS_SERVICE *) dll_get_next(
1722 (DLL *) Service_hash_table[i],
1723 (DLL *) servp)) )
1724 {
1725 ptr = wild_name;
1726 dptr = servp->serv_name;
1727 match = 1;
1728
1729 while( (ptr1 = strchr(ptr,'*')) )
1730 {
1731 if(ptr1 == ptr)
1732 {
1733 ptr++;
1734 if(!*ptr)
1735 {
1736 dptr = ptr;
1737 break;
1738 }
1739 strcpy(tmp,ptr);
1740 if( (ptr1 = strchr(ptr,'*')) )
1741 {
1742 tmp[ptr1-ptr] = '\0';
1743 }
1744 if( (dptr1 = strstr(dptr, tmp)) )
1745 {
1746 if(!ptr1)
1747 {
1748 dptr = dptr1;
1749 break;
1750 }
1751 dptr1 += strlen(tmp);
1752 ptr = ptr1;
1753 dptr = dptr1;
1754 }
1755 else
1756 {
1757 match = 0;
1758 break;
1759 }
1760 }
1761 else
1762 {
1763 strcpy(tmp,ptr);
1764 tmp[ptr1-ptr] = '\0';
1765 if(!strncmp(dptr, tmp, strlen(tmp)))
1766 {
1767 dptr += strlen(tmp);
1768 ptr = ptr1;
1769 }
1770 else
1771 {
1772 match = 0;
1773 break;
1774 }
1775 }
1776 }
1777 if(strcmp(dptr, ptr))
1778 {
1779 strcpy(tmp,ptr);
1780 strcat(tmp,"/RpcIn");
1781 if(strcmp(dptr, tmp))
1782 match = 0;
1783 }
1784 if(match)
1785 {
1786 if(servp->state == 1)
1787 {
1788 ptr = (char *)servp - (2 * sizeof(void *));
1789 Service_info_list[count] = (DNS_SERVICE *)ptr;
1790 count++;
1791 }
1792 }
1793 }
1794 }
1795 return(count);
1796}
1797
1798void set_rpc_info(int *tag, char *buffer, int *size)
1799{
1800 char aux[MAX_NAME], rpcaux[MAX_NAME+32], *ptr, *rpcptr;
1801 int i, n, rpc, id[2], conn_id;
1802 DNS_SERVICE *servp, *aux_servp;
1803
1804 if(size){}
1805 if(tag){}
1806 if(Debug)
1807 {
1808 dim_print_date_time();
1809 conn_id = dis_get_conn_id();
1810 printf(" Got Browse Request <%s> from conn: %d %s@%s\n", buffer, conn_id,
1811 Net_conns[conn_id].task,Net_conns[conn_id].node);
1812 }
1813 n = find_services(buffer);
1814 if(Debug)
1815 {
1816 dim_print_date_time();
1817 conn_id = dis_get_conn_id();
1818 printf(" Browse Request <%s> found %d services\n", buffer, n);
1819 }
1820 if(!Rpc_info_size)
1821 {
1822 Rpc_info = malloc(MAX_NAME*(n+1)*2);
1823 Rpc_info_size = MAX_NAME*(n+1)*2;
1824 }
1825 else if(Rpc_info_size < MAX_NAME*n*2)
1826 {
1827 free(Rpc_info);
1828 Rpc_info = malloc(MAX_NAME*(n+1)*2);
1829 Rpc_info_size = MAX_NAME*(n+1)*2;
1830 }
1831 Rpc_info[0] = '\0';
1832 rpcptr = Rpc_info;
1833 for(i = 0; i < n; i++)
1834 {
1835 rpc = 0;
1836 servp = Service_info_list[i];
1837 if(strstr(servp->serv_name,"/Rpc"))
1838 {
1839 strcpy(aux,servp->serv_name);
1840 if( (ptr = strstr(aux,"/RpcIn")) )
1841 {
1842 *ptr = '\0';
1843 rpc = 1;
1844 if( (ptr = strstr(Rpc_info, aux)) )
1845 {
1846 ptr += strlen(aux);
1847 if(*ptr == '|')
1848 rpc = 2;
1849 }
1850 }
1851 if( (ptr = strstr(aux,"/RpcOut")) )
1852 {
1853 *ptr = '\0';
1854 rpc = 1;
1855 if( (ptr = strstr(Rpc_info, aux)) )
1856 {
1857 ptr += strlen(aux);
1858 if(*ptr == '|')
1859 rpc = 2;
1860 }
1861 }
1862 if(rpc == 1)
1863 {
1864 strcpy(rpcaux, aux);
1865 strcat(rpcaux,"|");
1866 strcat(aux,"/RpcIn");
1867 if( (aux_servp = service_exists(aux)) )
1868 {
1869 strcat(rpcaux, aux_servp->serv_def);
1870 strcat(rpcaux,",");
1871 ptr = strstr(aux,"/RpcIn");
1872 *ptr = '\0';
1873 strcat(aux,"/RpcOut");
1874 if( (aux_servp = service_exists(aux)) )
1875 {
1876 strcat(rpcaux,aux_servp->serv_def);
1877 strcat(rpcaux,"|RPC\n");
1878 strcpy(rpcptr, rpcaux);
1879 rpcptr += strlen(rpcaux);
1880 }
1881 }
1882 }
1883 }
1884 else
1885 {
1886 strcpy(rpcaux, servp->serv_name);
1887 strcat(rpcaux,"|");
1888 strcat(rpcaux,servp->serv_def);
1889 if(servp->serv_id & 0x10000000)
1890 strcat(rpcaux,"|CMD\n");
1891 else
1892 strcat(rpcaux,"|\n");
1893 strcpy(rpcptr, rpcaux);
1894 rpcptr += strlen(rpcaux);
1895 }
1896 }
1897 *rpcptr = '\0';
1898 id[0] = dis_get_conn_id();
1899 id[1] = 0;
1900 dis_selective_update_service(Rpc_id, id);
1901 free(Service_info_list);
1902}
1903
1904void get_rpc_info(int *tag, char **buffer, int *size)
1905{
1906
1907 if(tag){}
1908 *buffer = Rpc_info;
1909 *size = strlen(Rpc_info)+1;
1910}
1911
Note: See TracBrowser for help on using the repository browser.