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

Last change on this file since 17689 was 15282, checked in by tbretz, 12 years ago
Updated to v20r7.
File size: 44.7 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 n_services;
182 char *ptr, *ptr1, *ptrt;
183 int found;
184 void do_update_did();
185 void do_inform_clients();
186 void inform_clients();
187 void service_init();
188 void service_insert();
189 void service_remove();
190#ifdef WIN32
191 extern int time();
192#endif
193#ifdef VMS
194 int format;
195#endif
196 int update_did = 0;
197 int name_too_long = 0;
198 int rem_only = 0;
199
200 Dns_conns[conn_id].validity = (int)time(NULL);
201 if( !Dns_conns[conn_id].service_head )
202 {
203
204 if(vtohl(packet->n_services) > 0)
205 {
206 service_id = vtohl(packet->services[0].service_id);
207 if((unsigned)service_id & 0x80000000)
208 rem_only = 1;
209 }
210/*
211 if( Debug )
212 {
213 dim_print_date_time();
214 printf( " !!!! New Conn %3d : Server %s@%s (PID %d) registering %d services, to delete %d\n",
215 conn_id, packet->task_name,
216 packet->node_name,
217 vtohl(packet->pid),
218 vtohl(packet->n_services), rem_only );
219 fflush(stdout);
220 }
221*/
222 if(rem_only)
223 return 0;
224
225 Dns_conns[conn_id].already = 0;
226 Dns_conns[conn_id].service_head =
227 (char *) malloc(sizeof(DNS_SERVICE));
228 dll_init( (DLL *) Dns_conns[conn_id].service_head );
229 Dns_conns[conn_id].n_services = 0;
230 Dns_conns[conn_id].timr_ent = NULL;
231 Curr_n_servers++;
232 Dns_conns[conn_id].src_type = SRC_DIS;
233 Dns_conns[conn_id].protocol = vtohl(packet->protocol);
234 strncpy( Dns_conns[conn_id].node_name, packet->node_name,
235 (size_t)MAX_NODE_NAME );
236 strncpy( Dns_conns[conn_id].task_name, packet->task_name,
237 (size_t)(MAX_TASK_NAME-4) );
238 strcpy(Dns_conns[conn_id].long_task_name, packet->task_name);
239 Dns_conns[conn_id].task_name[MAX_TASK_NAME-4-1] = '\0';
240 for(i = 0; i < 4; i++)
241 Dns_conns[conn_id].node_addr[i] = packet->node_addr[i];
242 Dns_conns[conn_id].pid = vtohl(packet->pid);
243 Dns_conns[conn_id].port = vtohl(packet->port);
244/*
245 if( Debug )
246 {
247 dim_print_date_time();
248 printf( " !!!! New Conn %3d : Server %s@%s (PID %d) registered %d services\n",
249 conn_id, Dns_conns[conn_id].task_name,
250 Dns_conns[conn_id].node_name,
251 Dns_conns[conn_id].pid,
252 vtohl(packet->n_services) );
253 fflush(stdout);
254 }
255*/
256
257
258 if(strcmp(Dns_conns[conn_id].task_name,"DIS_DNS"))
259 if(DNS_accepted_domains[0] == 0)
260 {
261 if(!get_dns_accepted_domains(DNS_accepted_domains))
262 DNS_accepted_domains[0] = -1;
263 }
264 if((DNS_accepted_domains[0] != -1) && (strcmp(Dns_conns[conn_id].task_name,"DIS_DNS")))
265 {
266 ptr = DNS_accepted_domains;
267 found = 0;
268 while(*ptr)
269 {
270 ptr1 = strchr(ptr,',');
271 if(ptr1)
272 {
273 *ptr1 = '\0';
274 ptr1++;
275 }
276 else
277 {
278 ptr1 = ptr;
279 ptr1 += (int)strlen(ptr);
280 }
281 if(strstr(Dns_conns[conn_id].node_name,ptr))
282 {
283 found = 1;
284 break;
285 }
286 ptr = ptr1;
287 }
288 if(!found)
289 {
290 dis_packet.type = htovl(DNS_DIS_STOP);
291 dis_packet.size = htovl(DNS_DIS_HEADER);
292 if( !dna_write_nowait(conn_id, &dis_packet, DNS_DIS_HEADER) )
293 {
294 dim_print_date_time();
295 printf(" Stop Server: Couldn't write, releasing %d\n",conn_id);
296 fflush(stdout);
297 }
298 dim_print_date_time();
299 printf(" Connection from %s refused, stopping server %s\n",
300 Dns_conns[conn_id].node_name,
301 Dns_conns[conn_id].task_name);
302 fflush(stdout);
303 release_conn(conn_id);
304
305 return 0;
306 }
307 }
308 if(tmout_flag)
309 Dns_conns[conn_id].timr_ent = dtq_add_entry( Timer_q,
310 (int)(WATCHDOG_TMOUT_MAX * 1.3), check_validity, conn_id);
311 if(strcmp(Dns_conns[conn_id].task_name,"DIS_DNS"))
312 {
313 dna_set_test_write(conn_id, dim_get_keepalive_timeout());
314 }
315 Dns_conns[conn_id].old_n_services = 0;
316/*
317 Dns_conns[conn_id].n_services = 1;
318 do_update_did(conn_id);
319*/
320 update_did = 1;
321/*
322 Dns_conns[conn_id].old_n_services = 0;
323*/
324 Dns_conns[conn_id].n_services = 0;
325 }
326 else
327 {
328 if( (Dns_conns[conn_id].n_services == -1) &&
329 vtohl(packet->n_services) )
330 {
331 if(strcmp(Dns_conns[conn_id].task_name,"DIS_DNS"))
332 dna_set_test_write(conn_id, dim_get_keepalive_timeout());
333 dim_print_date_time();
334 printf( " Server %s out of error\n",
335 Dns_conns[conn_id].task_name );
336 fflush(stdout);
337 Dns_conns[conn_id].n_services = 0;
338 }
339 }
340 n_services = vtohl(packet->n_services);
341 if((int)strlen(Dns_conns[conn_id].task_name) == MAX_TASK_NAME-4-1)
342 name_too_long = 1;
343 for( i = 0; i < n_services; i++ )
344 {
345/*
346 if( Debug )
347 {
348 dim_print_date_time();
349 printf( " Conn %3d : Server %s@%s (PID %d) registered %s\n",
350 conn_id, Dns_conns[conn_id].task_name,
351 Dns_conns[conn_id].node_name,
352 Dns_conns[conn_id].pid,
353 packet->services[i].service_name );
354 fflush(stdout);
355 }
356*/
357 if(n_services == 1)
358 {
359 if(!strcmp(packet->services[i].service_name, "DUMMY_UPDATE_PACKET"))
360 {
361 do_inform_clients(conn_id);
362 break;
363 }
364 }
365 if( (servp = service_exists(packet->services[i].service_name)) )
366 {
367 /* if service available on another server send kill signal */
368 if((servp->conn_id) && (servp->conn_id != conn_id))
369 {
370 dis_packet.type = htovl(DNS_DIS_KILL);
371 dis_packet.size = htovl(DNS_DIS_HEADER);
372#ifdef VMS
373 format = vtohl(packet->format);
374 if((format & MY_OS9) || (servp->state == -1))
375 {
376 Dns_conns[servp->conn_id].already = 1;
377 if( !dna_write(servp->conn_id, &dis_packet, DNS_DIS_HEADER) )
378 {
379 dim_print_date_time();
380 printf(" Couldn't write, releasing %d\n",servp->conn_id);
381 fflush(stdout);
382 }
383 dim_print_date_time();
384 printf(" Service %s already declared, killing server %s\n",
385 servp->serv_name, Dns_conns[servp->conn_id].task_name);
386 fflush(stdout);
387 release_client(servp->conn_id);
388 release_conn(servp->conn_id);
389 }
390 else
391 {
392#endif
393 if((Dns_conns[servp->conn_id].port == Dns_conns[conn_id].port) &&
394 (!strcmp(Dns_conns[servp->conn_id].node_name, Dns_conns[conn_id].node_name)))
395 {
396 dim_print_date_time();
397printf(" Service %s already declared by conn %d - %s@%s:%d (PID %d), Redeclared by conn %d - %s@%s:%d (PID %d)(same server) - Closing old conn %d\n",
398 servp->serv_name, servp->conn_id,
399 Dns_conns[servp->conn_id].task_name,
400 Dns_conns[servp->conn_id].node_name,
401 Dns_conns[servp->conn_id].port,
402 Dns_conns[servp->conn_id].pid,
403 conn_id,
404 Dns_conns[conn_id].task_name,
405 Dns_conns[conn_id].node_name,
406 Dns_conns[conn_id].port,
407 Dns_conns[conn_id].pid,
408 servp->conn_id);
409 fflush(stdout);
410 release_conn(servp->conn_id);
411 update_did = 0;
412/*
413 return(0);
414*/
415 }
416 else
417 {
418 Dns_conns[conn_id].already = 1;
419
420 if( !dna_write_nowait(conn_id, &dis_packet, DNS_DIS_HEADER) )
421 {
422 dim_print_date_time();
423 printf(" Kill Server: Couldn't write, releasing %d\n",conn_id);
424 fflush(stdout);
425 }
426 dim_print_date_time();
427printf(" Service %s already declared by conn %d - %s@%s:%d (PID %d), killing server conn %d - %s@%s:%d (PID %d) \n",
428 servp->serv_name, servp->conn_id,
429 Dns_conns[servp->conn_id].task_name,
430 Dns_conns[servp->conn_id].node_name,
431 Dns_conns[servp->conn_id].port,
432 Dns_conns[servp->conn_id].pid,
433 conn_id,
434 Dns_conns[conn_id].task_name,
435 Dns_conns[conn_id].node_name,
436 Dns_conns[conn_id].port,
437 Dns_conns[conn_id].pid);
438 fflush(stdout);
439
440 release_conn(conn_id);
441
442 return(0);
443 }
444#ifdef VMS
445 }
446#endif
447 }
448 else if( servp->state != -1 )
449 {
450 if( !dll_empty((DLL *) servp->node_head))
451 {
452 /*there are interested clients waiting*/
453 strncpy( servp->serv_def,
454 packet->services[i].service_def,(size_t)MAX_NAME );
455 servp->conn_id = conn_id;
456 servp->state = 1;
457 servp->server_format = vtohl(packet->format);
458 servp->serv_id = vtohl(packet->services[i].service_id);
459 dll_insert_queue((DLL *)
460 Dns_conns[conn_id].service_head,
461 (DLL *) servp);
462 Dns_conns[conn_id].n_services++;
463
464/*
465 if(n_services == 1)
466*/
467 if(n_services < MAX_REGISTRATION_UNIT)
468 {
469 inform_clients(servp);
470 }
471 continue;
472 }
473 else
474 {
475 /* test if Service is to be removed */
476 service_id = vtohl(packet->services[i].service_id);
477 if((unsigned)service_id & 0x80000000)
478 {
479 dll_remove((DLL *) servp);
480 service_remove(&(servp->next));
481 Curr_n_services--;
482 free(servp);
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 (size_t)MAX_NAME);
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 (size_t)MAX_NAME );
535 strncpy( servp->serv_def,
536 packet->services[i].service_def,
537 (size_t)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 = (int)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 += (int)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( (unsigned)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, (size_t)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 void inform_clients();
946
947 DISABLE_AST
948 if(!Dns_conns[conn_id].service_head)
949 {
950 prev_servp = (DNS_SERVICE *)0;
951 ENABLE_AST
952 return;
953 }
954 if(prev_servp)
955 servp = prev_servp;
956 else
957 servp = (DNS_SERVICE *)Dns_conns[conn_id].service_head;
958 while( (servp = (DNS_SERVICE *) dll_get_next(
959 (DLL *) Dns_conns[conn_id].service_head,
960 (DLL *) servp)) )
961 {
962 if( servp->state != -1 )
963 {
964 if( !dll_empty((DLL *) servp->node_head))
965 {
966 inform_clients(servp);
967 n_informed++;
968 if(n_informed == 1000)
969 {
970 dtq_start_timer(0, do_inform_clients, conn_id);
971 ENABLE_AST
972 return;
973 }
974 }
975 }
976 }
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, to_release = 0;
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 to_release = nodep->conn_id;
1019/*
1020release_conn(nodep->conn_id);
1021*/
1022 }
1023/*
1024 if(dna_write_nowait(nodep->conn_id, &packet, DNS_DIC_HEADER))
1025 {
1026*/
1027 dll_remove( (DLL *) nodep );
1028 ptr = (char *)nodep - (2 * sizeof(void *));
1029 full_nodep = (NODE *)ptr;
1030 dll_remove( (DLL *) full_nodep );
1031 nodep = nodep->prev;
1032 free( full_nodep );
1033 prevp = nodep;
1034/*
1035 }
1036*/
1037 }
1038 if(to_release)
1039 release_conn(to_release);
1040}
1041
1042#ifdef VMS
1043static release_client(int conn_id)
1044{
1045char *ptr_task;
1046char *ptr_node;
1047int i;
1048
1049 ptr_task = Net_conns[conn_id].task;
1050 ptr_node = Net_conns[conn_id].node;
1051 for( i = 0; i< Curr_N_Conns; i++ )
1052 {
1053 if( (!strcmp(Net_conns[i].task,ptr_task)) &&
1054 (!strcmp(Net_conns[i].node,ptr_node)) )
1055 {
1056 if(i != conn_id)
1057 {
1058 if( Dns_conns[i].src_type == SRC_DIC )
1059 {
1060 if(Debug)
1061 {
1062 dim_print_date_time();
1063 printf(" Releasing client on conn %d - %s@%s\n",
1064 i, Net_conns[i].task, Net_conns[i].node);
1065 fflush(stdout);
1066 }
1067 release_conn(i);
1068 }
1069 }
1070 }
1071 }
1072}
1073#endif
1074
1075static void release_conn(int conn_id)
1076{
1077 DNS_SERVICE *servp, *old_servp;
1078 NODE *nodep, *old_nodep;
1079 void service_remove();
1080
1081 if( Dns_conns[conn_id].src_type == SRC_DIS )
1082 {
1083 if( Debug )
1084 {
1085 dim_print_date_time();
1086 printf( " Conn %3d : Server %s@%s died\n",
1087 conn_id, Dns_conns[conn_id].task_name,
1088 Dns_conns[conn_id].node_name);
1089 fflush(stdout);
1090 }
1091 else
1092 {
1093 if(Dns_conns[conn_id].n_services == -1)
1094 {
1095 dim_print_date_time();
1096 printf( " Conn %3d : Server %s@%s died\n",
1097 conn_id, Dns_conns[conn_id].task_name,
1098 Dns_conns[conn_id].node_name);
1099 fflush(stdout);
1100 }
1101 }
1102 Curr_n_servers--;
1103 if( Dns_conns[conn_id].timr_ent )
1104 {
1105 dtq_rem_entry( Timer_q, Dns_conns[conn_id].timr_ent );
1106 Dns_conns[conn_id].timr_ent = NULL;
1107 }
1108 servp = (DNS_SERVICE *)Dns_conns[conn_id].service_head;
1109 while( (servp = (DNS_SERVICE *) dll_get_next(
1110 (DLL *) Dns_conns[conn_id].service_head,
1111 (DLL *) servp)) )
1112 {
1113 dll_remove((DLL *) servp);
1114 if(dll_empty((DLL *) servp->node_head))
1115 {
1116 service_remove(&(servp->next));
1117 Curr_n_services--;
1118 old_servp = servp;
1119 servp = servp->server_prev;
1120 free(old_servp);
1121 }
1122 else
1123 {
1124 servp->state = 0;
1125 servp->conn_id = 0;
1126 servp = servp->server_prev;
1127 }
1128 }
1129 if(Dns_conns[conn_id].n_services)
1130 {
1131 Dns_conns[conn_id].n_services = 0;
1132
1133 do_update_did(conn_id);
1134/*
1135 Last_conn_id = conn_id;
1136 dis_update_service(Server_new_info_id);
1137 dis_update_service(Server_info_id);
1138*/
1139 }
1140 free((DNS_SERVICE *)Dns_conns[conn_id].service_head);
1141 Dns_conns[conn_id].service_head = 0;
1142 Dns_conns[conn_id].src_type = SRC_NONE;
1143 dna_close(conn_id);
1144 }
1145 else if(Dns_conns[conn_id].src_type == SRC_DIC)
1146 {
1147 if(Debug)
1148 {
1149 dim_print_date_time();
1150 printf(" Conn %3d : Client %s@%s died\n",
1151 conn_id, Net_conns[conn_id].task, Net_conns[conn_id].node);
1152 fflush(stdout);
1153 }
1154 if( (nodep = (NODE *)Dns_conns[conn_id].node_head) )
1155 {
1156 while( (nodep = (NODE *) dll_get_next(
1157 (DLL *) Dns_conns[conn_id].node_head,
1158 (DLL *) nodep)) )
1159 {
1160 servp = nodep->servp;
1161 dll_remove( (DLL *) nodep );
1162 dll_remove( (DLL *) &(nodep->next) );
1163 old_nodep = nodep;
1164 nodep = nodep->client_prev;
1165 free(old_nodep);
1166 if( (dll_empty((DLL *) servp->node_head)) &&
1167 (!servp->conn_id) )
1168 {
1169 service_remove(&(servp->next));
1170 Curr_n_services--;
1171 free( servp );
1172 }
1173 }
1174 free(Dns_conns[conn_id].node_head);
1175 Dns_conns[conn_id].node_head = 0;
1176 }
1177 Dns_conns[conn_id].src_type = SRC_NONE;
1178 dna_close(conn_id);
1179 }
1180 else
1181 {
1182 if(Debug)
1183 {
1184 dim_print_date_time();
1185 printf(" Conn %3d : Undefined Type %s@%s died\n",
1186 conn_id, Net_conns[conn_id].task,
1187 Net_conns[conn_id].node);
1188 fflush(stdout);
1189 }
1190 dna_close(conn_id);
1191 }
1192}
1193
1194
1195void set_in_error(int conn_id)
1196{
1197 DNS_SERVICE *servp;
1198
1199 if(Dns_conns[conn_id].src_type == SRC_DIS)
1200 {
1201 if(strcmp(Dns_conns[conn_id].task_name,"DIS_DNS"))
1202 dna_rem_test_write(conn_id);
1203 servp = (DNS_SERVICE *)Dns_conns[conn_id].service_head;
1204 while( (servp = (DNS_SERVICE *) dll_get_next(
1205 (DLL *) Dns_conns[conn_id].service_head,
1206 (DLL *) servp)) )
1207 servp->state = -1;
1208 Dns_conns[conn_id].n_services = -1;
1209 }
1210}
1211
1212void get_dns_server_info(int *tag, int **bufp, int *size, int *first_time)
1213{
1214 if(tag){}
1215 if(*first_time)
1216 {
1217
1218#ifdef VMS
1219 sys$wake(0, 0);
1220#else
1221 wake_up = TRUE;
1222#ifdef WIN32
1223 wake_up();
1224#endif
1225#endif
1226 *size = 0;
1227 }
1228 else
1229 {
1230 send_dns_server_info(Last_conn_id, bufp, size);
1231 }
1232}
1233
1234
1235void send_dns_server_info(int conn_id, int **bufp, int *size)
1236{
1237 static int curr_allocated_size = 0;
1238 static DNS_DID *dns_info_buffer;
1239 DNS_SERVICE *servp;
1240 DNS_SERVER_INFO *dns_server_info;
1241 DNS_SERVICE_INFO *dns_service_info;
1242 DNS_CONNECTION *connp;
1243 int max_size;
1244 int n_services;
1245
1246 DISABLE_AST
1247 connp = &Dns_conns[conn_id];
1248 if(connp->src_type != SRC_DIS)
1249 {
1250 ENABLE_AST
1251 return;
1252 }
1253 n_services = connp->n_services;
1254 if(n_services == -1)
1255 n_services = 0;
1256 max_size = (int)sizeof(DNS_SERVER_INFO) +
1257 n_services * (int)sizeof(DNS_SERVICE_INFO);
1258 if(!curr_allocated_size)
1259 {
1260 dns_info_buffer = (DNS_DID *)malloc((size_t)max_size);
1261 curr_allocated_size = max_size;
1262 }
1263 else if (max_size > curr_allocated_size)
1264 {
1265 free(dns_info_buffer);
1266 dns_info_buffer = (DNS_DID *)malloc((size_t)max_size);
1267 curr_allocated_size = max_size;
1268 }
1269 dns_server_info = &dns_info_buffer->server;
1270 dns_service_info = dns_info_buffer->services;
1271 strncpy(dns_server_info->task, connp->task_name, (size_t)(MAX_TASK_NAME-4));
1272 strncpy(dns_server_info->node, connp->node_name, (size_t)MAX_NODE_NAME);
1273 dns_server_info->pid = htovl(connp->pid);
1274 dns_server_info->n_services = htovl(connp->n_services);
1275 servp = (DNS_SERVICE *)connp->service_head;
1276 while( (servp = (DNS_SERVICE *) dll_get_next((DLL *) connp->service_head,
1277 (DLL *) servp)) )
1278 {
1279 strncpy(dns_service_info->name, servp->serv_name, (size_t)MAX_NAME);
1280 dns_service_info->status = htovl(1);
1281 if(servp->serv_id & 0x10000000)
1282 dns_service_info->type = htovl(1);
1283 else
1284 dns_service_info->type = htovl(0);
1285 dns_service_info++;
1286 }
1287 *bufp = (int *)dns_info_buffer;
1288 *size = max_size;
1289 ENABLE_AST
1290}
1291
1292void get_new_dns_server_info(int *tag, int **bufp, int *size, int *first_time)
1293{
1294 static int curr_allocated_size = 0;
1295 static char *info_buffer;
1296 static int *pid_buffer, pid_size;
1297 int pid_index = 0;
1298 DNS_CONNECTION *connp;
1299 int i, max_size, max_pid_size/*, j, n*/;
1300 int n_server = 0;
1301 char /*aux[MAX_NAME], *ptr, */ server[MAX_NAME], *info_buffer_ptr;
1302/*
1303 DNS_SERVICE *servp;
1304 int find_services();
1305*/
1306
1307 DISABLE_AST
1308 if(tag){}
1309 for( i = 0; i< Curr_N_Conns; i++ )
1310 {
1311 if( Dns_conns[i].src_type == SRC_DIS )
1312 {
1313 n_server++;
1314 }
1315 }
1316 max_size = ((int)sizeof(DNS_SERVER_INFO) + MAX_TASK_NAME) * n_server;
1317 max_pid_size = (int)sizeof(int) * n_server;
1318 if(!curr_allocated_size)
1319 {
1320 info_buffer = (char *)malloc((size_t)max_size);
1321 curr_allocated_size = max_size;
1322 pid_buffer = (int *)malloc((size_t)max_pid_size);
1323 }
1324 else if (max_size > curr_allocated_size)
1325 {
1326 free(info_buffer);
1327 info_buffer = (char *)malloc((size_t)max_size);
1328 curr_allocated_size = max_size;
1329 free(pid_buffer);
1330 pid_buffer = (int *)malloc((size_t)max_pid_size);
1331 }
1332 info_buffer[0] = '\0';
1333 pid_buffer[0] = 0;
1334
1335 info_buffer_ptr = info_buffer;
1336 if(*first_time)
1337 {
1338 for( i = 0; i< Curr_N_Conns; i++ )
1339 {
1340 if( Dns_conns[i].src_type == SRC_DIS )
1341 {
1342 connp = &Dns_conns[i];
1343/*
1344 if((int)strlen(connp->task_name) == MAX_TASK_NAME-4-1)
1345 {
1346 strcpy(aux,connp->task_name);
1347 strcat(aux,"--CLIENT_LIST");
1348 n = find_services(aux);
1349 for(j = 0; j < n; j++)
1350 {
1351 servp = Service_info_list[j];
1352 if(i == servp->conn_id)
1353 {
1354 strcpy(aux,servp->serv_name);
1355 ptr = strstr(aux,"/CLIENT_LIST");
1356 if(ptr)
1357 *ptr = '\0';
1358 break;
1359 }
1360 }
1361 free(Service_info_list);
1362 strcpy(server, aux);
1363 }
1364 else
1365 {
1366*/
1367 strcpy(server, connp->long_task_name);
1368/*
1369 }
1370*/
1371 strcat(server,"@");
1372 strcat(server, connp->node_name);
1373 strcat(server,"|");
1374 strcpy(info_buffer_ptr, server);
1375 info_buffer_ptr += (int)strlen(server);
1376 pid_buffer[pid_index] = connp->pid;
1377 pid_index++;
1378 }
1379 }
1380 }
1381 else
1382 {
1383 connp = &Dns_conns[Last_conn_id];
1384 if(connp->n_services > 0)
1385 strcat(info_buffer, "+");
1386 else if(connp->n_services == -1)
1387 strcat(info_buffer, "!");
1388 else
1389 strcat(info_buffer, "-");
1390 strcat(info_buffer, connp->long_task_name);
1391 strcat(info_buffer,"@");
1392 strcat(info_buffer, connp->node_name);
1393 strcat(info_buffer,"|");
1394 pid_buffer[pid_index] = connp->pid;
1395 pid_index++;
1396 }
1397 info_buffer[(int)strlen(info_buffer) - 1] = '\0';
1398 info_buffer_ptr = &info_buffer[(int)strlen(info_buffer)+1];
1399 pid_size = 0;
1400 for(i = 0; i < pid_index; i++)
1401 {
1402 if(i != (pid_index -1))
1403 sprintf(server, "%d|",pid_buffer[i]);
1404 else
1405 sprintf(server, "%d",pid_buffer[i]);
1406 strcpy(info_buffer_ptr, server);
1407 info_buffer_ptr += (int)strlen(server);
1408 pid_size += (int)strlen(server);
1409 }
1410 *bufp = (int *)info_buffer;
1411 *size = (int)strlen(info_buffer)+1+pid_size+1;
1412 ENABLE_AST
1413}
1414
1415int main(int argc, char **argv)
1416{
1417 int i, protocol, dns_port;
1418 int *bufp;
1419 int size;
1420 int conn_id, id;
1421 DIS_DNS_PACKET *dis_dns_packet;
1422 char node[MAX_NAME];
1423 void service_init();
1424
1425 if(argc > 1)
1426 {
1427 if(!strcmp(argv[1],"-d"))
1428 set_debug_on();
1429 else
1430 {
1431 printf("Parameters: -d Debug On\n");
1432 exit(0);
1433 }
1434 }
1435 dim_set_write_timeout(10);
1436 dim_set_listen_backlog(1024);
1437 dim_init();
1438 conn_arr_create( SRC_DNS );
1439 service_init();
1440 Timer_q = dtq_create();
1441 get_node_name(node);
1442 dim_print_date_time();
1443 printf(" DNS version %d starting up on %s\n",DIM_VERSION_NUMBER, node);
1444 fflush(stdout);
1445
1446 Server_new_info_id =(int) dis_add_service( "DIS_DNS/SERVER_LIST", "C", 0, 0,
1447 get_new_dns_server_info, 0 );
1448 Server_info_id = (int)dis_add_service( "DIS_DNS/SERVER_INFO", 0, 0, 0,
1449 get_dns_server_info, 0 );
1450 dis_add_cmnd( "DIS_DNS/PRINT_STATS", 0, print_stats, 0 );
1451 dis_add_cmnd( "DIS_DNS/DEBUG_ON", 0, set_debug_on, 0 );
1452 dis_add_cmnd( "DIS_DNS/DEBUG_OFF", 0, set_debug_off, 0 );
1453 dis_add_cmnd( "DIS_DNS/KILL_SERVERS", "I", kill_servers, 0 );
1454 dis_add_cmnd( "DIS_DNS/PRINT_HASH_TABLE", 0, print_hash_table, 0 );
1455 dis_add_cmnd( "DIS_DNS/SERVICE_INFO/RpcIn", "C", set_rpc_info, 0 );
1456 Rpc_id = (int)dis_add_service( "DIS_DNS/SERVICE_INFO/RpcOut", "C", 0, 0,
1457 get_rpc_info, 0 );
1458 dns_port = get_dns_port_number();
1459 if( !dna_open_server(DNS_TASK, recv_rout, &protocol, &dns_port, error_handler) )
1460 return(0);
1461
1462 id = dis_start_serving("DIS_DNS");
1463 dis_dns_packet = (DIS_DNS_PACKET *) id_get_ptr(id, SRC_DIS);
1464 id_free(id, SRC_DIS);
1465 conn_id = conn_get();
1466 handle_registration(conn_id, dis_dns_packet, 0);
1467 dtq_add_entry(Timer_q, 5, update_did, 0xded0000);
1468 while(1)
1469 {
1470#ifdef VMS
1471 sys$hiber();
1472#else
1473 wake_up = FALSE;
1474 while( !wake_up )
1475 {
1476 dim_wait();
1477 }
1478#endif
1479 for( i = 0; i< Curr_N_Conns; i++ )
1480 {
1481 if( Dns_conns[i].src_type == SRC_DIS )
1482 {
1483 send_dns_server_info( i, &bufp, &size );
1484 dis_send_service( Server_info_id, bufp, size );
1485 }
1486 }
1487 }
1488 return(1);
1489}
1490
1491
1492void print_stats()
1493{
1494 int i;
1495 int n_conns = 0;
1496 int n_services = 0;
1497 int n_servers = 0;
1498 int n_clients = 0;
1499
1500 dim_print_date_time();
1501 printf(" Connection Statistics :\n");
1502 for(i = 0; i< Curr_N_Conns; i++)
1503 {
1504 switch(Dns_conns[i].src_type)
1505 {
1506 case SRC_DIS :
1507 printf("%d - Server %s@%s (PID %d) %d services\n",
1508 i, Dns_conns[i].task_name,
1509 Dns_conns[i].node_name,
1510 Dns_conns[i].pid, Dns_conns[i].n_services);
1511 fflush(stdout);
1512 n_services += Dns_conns[i].n_services;
1513 n_servers++;
1514 n_conns++;
1515 break;
1516 case SRC_DIC :
1517 printf("%d - Client %s@%s\n",
1518 i, Net_conns[i].task, Net_conns[i].node);
1519 fflush(stdout);
1520 n_conns++;
1521 n_clients++;
1522 break;
1523 default :
1524 if(Dna_conns[i].busy)
1525 {
1526 if(Net_conns[i].task[0] && Net_conns[i].node[0])
1527 printf("%d - Undefined %s@%s\n",
1528 i, Net_conns[i].task,
1529 Net_conns[i].node);
1530 else
1531 printf("%d - Undefined\n", i);
1532 fflush(stdout);
1533 n_conns++;
1534 }
1535 else
1536 {
1537 printf("%d - Empty\n", i);
1538 fflush(stdout);
1539 }
1540 }
1541 }
1542 printf("Number of Connections = %d : %d servers, %d clients\n", n_conns,
1543 n_servers, n_clients);
1544 printf("Number of Services = %d\n", n_services);
1545 fflush(stdout);
1546}
1547
1548
1549void set_debug_on()
1550{
1551 Debug = 1;
1552}
1553
1554
1555void set_debug_off()
1556{
1557 Debug = 0;
1558}
1559
1560
1561void kill_servers(int *tag, int *code, int *size)
1562{
1563 int i;
1564 DNS_DIS_PACKET dis_packet;
1565 int soft_code = 0, soft_size = 0;
1566 int type;
1567
1568 if(tag){}
1569 if(size)
1570 {
1571 soft_size = *size;
1572 if(code)
1573 {
1574 soft_code = *code;
1575 }
1576 }
1577 for(i = 0; i< Curr_N_Conns; i++)
1578 {
1579 if(Dns_conns[i].src_type == SRC_DIS)
1580 {
1581 if(!strcmp(Dns_conns[i].task_name,"DIS_DNS"))
1582 continue;
1583 fflush(stdout);
1584 type = DNS_DIS_EXIT;
1585 if(soft_size)
1586 {
1587 type = DNS_DIS_SOFT_EXIT;
1588 type |= (soft_code << (int)16) & (int)0xFFFF0000;
1589 dim_print_date_time();
1590 printf(" Killing server %s@%s with exit code %d\n",
1591 Dns_conns[i].task_name, Dns_conns[i].node_name, soft_code);
1592 }
1593 else
1594 {
1595 dim_print_date_time();
1596 printf(" Killing server %s@%s\n",
1597 Dns_conns[i].task_name, Dns_conns[i].node_name);
1598 }
1599 dis_packet.type = htovl(type);
1600 dis_packet.size = htovl(DNS_DIS_HEADER);
1601 if( !dna_write_nowait(i, &dis_packet, DNS_DIS_HEADER) )
1602 {
1603 dim_print_date_time();
1604 printf(" Kill Server: Couldn't write, releasing %d\n",i);
1605 fflush(stdout);
1606 release_conn(i);
1607 }
1608 }
1609 }
1610}
1611
1612
1613void service_init()
1614{
1615 int i;
1616
1617 for( i = 0; i < MAX_HASH_ENTRIES; i++ ) {
1618 Service_hash_table[i] = (RED_DNS_SERVICE *) malloc(sizeof(RED_DNS_SERVICE));
1619 dll_init((DLL *) Service_hash_table[i]);
1620 }
1621}
1622
1623
1624void service_insert(RED_DNS_SERVICE *servp)
1625{
1626 int index;
1627
1628 index = HashFunction(servp->serv_name, MAX_HASH_ENTRIES);
1629 dll_insert_queue((DLL *) Service_hash_table[index],
1630 (DLL *) servp);
1631}
1632
1633
1634void service_remove(RED_DNS_SERVICE *servp)
1635{
1636 if( servp->node_head )
1637 free( servp->node_head );
1638 dll_remove( (DLL *) servp );
1639}
1640
1641
1642DNS_SERVICE *service_exists(char *name)
1643{
1644 int index;
1645 RED_DNS_SERVICE *servp;
1646 char *ptr;
1647
1648 index = HashFunction(name, MAX_HASH_ENTRIES);
1649 if( (servp = (RED_DNS_SERVICE *) dll_search(
1650 (DLL *) Service_hash_table[index],
1651 name, (int)strlen(name)+1)) )
1652 {
1653 ptr = (char *)servp - (2 * sizeof(void *));
1654 return((DNS_SERVICE *)ptr);
1655 }
1656
1657 return((DNS_SERVICE *)0);
1658}
1659
1660void print_hash_table()
1661{
1662 int i;
1663 RED_DNS_SERVICE *servp;
1664 int n_entries, max_entry_index = 0;
1665 int max_entries = 0;
1666
1667#ifdef VMS
1668 if( ( foutptr = fopen( "scratch$week:[cp_operator]dim_dns.log", "w" )
1669 ) == (FILE *)0 )
1670 {
1671 printf("Cannot open: scratch$week:[cp_operator]dim_dns.log for writing\n");
1672 fflush(stdout);
1673 return;
1674 }
1675#endif
1676
1677 for( i = 0; i < MAX_HASH_ENTRIES; i++ )
1678 {
1679 n_entries = 0;
1680#ifdef VMS
1681 fprintf(foutptr,"HASH[%d] : \n",i);
1682#endif
1683 servp = Service_hash_table[i];
1684 while( (servp = (RED_DNS_SERVICE *) dll_get_next(
1685 (DLL *) Service_hash_table[i],
1686 (DLL *) servp)) )
1687 {
1688#ifdef VMS
1689 fprintf(foutptr,"%s\n",servp->serv_name);
1690#endif
1691 n_entries++;
1692 }
1693#ifdef VMS
1694 fprintf(foutptr,"\n\n");
1695#endif
1696 if(n_entries != 0)
1697 printf("HASH[%d] - %d entries\n", i, n_entries);
1698 if(n_entries > max_entries)
1699 {
1700 max_entries = n_entries;
1701 max_entry_index = i;
1702 }
1703 }
1704#ifdef VMS
1705 fclose(foutptr);
1706#endif
1707 printf("Maximum : HASH[%d] - %d entries\n", max_entry_index, max_entries);
1708 fflush(stdout);
1709}
1710
1711int find_services(char *wild_name)
1712{
1713
1714 int i;
1715 RED_DNS_SERVICE *servp;
1716 DNS_SERVICE *servp1;
1717 char tmp[MAX_NAME], *ptr, *ptr1, *dptr, *dptr1;
1718 int match, count = 0;
1719
1720 Service_info_list = (DNS_SERVICE **)
1721 malloc((size_t)(Curr_n_services*(int)sizeof(DNS_SERVICE *)));
1722
1723 if(!strchr(wild_name, '*'))
1724 {
1725 servp1 = service_exists(wild_name);
1726 if(servp1)
1727 {
1728 if(servp1->state == 1)
1729 {
1730 Service_info_list[count] = (DNS_SERVICE *)servp1;
1731 count++;
1732 return 1;
1733 }
1734 }
1735 return 0;
1736 }
1737 for( i = 0; i < MAX_HASH_ENTRIES; i++ )
1738 {
1739 servp = Service_hash_table[i];
1740 while( (servp = (RED_DNS_SERVICE *) dll_get_next(
1741 (DLL *) Service_hash_table[i],
1742 (DLL *) servp)) )
1743 {
1744 ptr = wild_name;
1745 dptr = servp->serv_name;
1746 match = 1;
1747
1748 while( (ptr1 = strchr(ptr,'*')) )
1749 {
1750 if(ptr1 == ptr)
1751 {
1752 ptr++;
1753 if(!*ptr)
1754 {
1755 dptr = ptr;
1756 break;
1757 }
1758 strcpy(tmp,ptr);
1759 if( (ptr1 = strchr(ptr,'*')) )
1760 {
1761 tmp[ptr1-ptr] = '\0';
1762 }
1763 if( (dptr1 = strstr(dptr, tmp)) )
1764 {
1765 if(!ptr1)
1766 {
1767 dptr = dptr1;
1768 break;
1769 }
1770 dptr1 += (int)strlen(tmp);
1771 ptr = ptr1;
1772 dptr = dptr1;
1773 }
1774 else
1775 {
1776 match = 0;
1777 break;
1778 }
1779 }
1780 else
1781 {
1782 strcpy(tmp,ptr);
1783 tmp[ptr1-ptr] = '\0';
1784 if(!strncmp(dptr, tmp, strlen(tmp)))
1785 {
1786 dptr += (int)strlen(tmp);
1787 ptr = ptr1;
1788 }
1789 else
1790 {
1791 match = 0;
1792 break;
1793 }
1794 }
1795 }
1796 if(strcmp(dptr, ptr))
1797 {
1798 strcpy(tmp,ptr);
1799 strcat(tmp,"/RpcIn");
1800 if(strcmp(dptr, tmp))
1801 match = 0;
1802 }
1803 if(match)
1804 {
1805 if(servp->state == 1)
1806 {
1807 ptr = (char *)servp - (2 * sizeof(void *));
1808 Service_info_list[count] = (DNS_SERVICE *)ptr;
1809 count++;
1810 }
1811 }
1812 }
1813 }
1814 return(count);
1815}
1816
1817void set_rpc_info(int *tag, char *buffer, int *size)
1818{
1819 char aux[MAX_NAME], rpcaux[MAX_NAME+32], *ptr, *rpcptr;
1820 int i, n, rpc, id[2], conn_id;
1821 DNS_SERVICE *servp, *aux_servp;
1822
1823 if(size){}
1824 if(tag){}
1825 if(Debug)
1826 {
1827 dim_print_date_time();
1828 conn_id = dis_get_conn_id();
1829 printf(" Got Browse Request <%s> from conn: %d %s@%s\n", buffer, conn_id,
1830 Net_conns[conn_id].task,Net_conns[conn_id].node);
1831 }
1832 n = find_services(buffer);
1833 if(Debug)
1834 {
1835 dim_print_date_time();
1836 conn_id = dis_get_conn_id();
1837 printf(" Browse Request <%s> found %d services\n", buffer, n);
1838 }
1839 if(!Rpc_info_size)
1840 {
1841 Rpc_info = malloc((size_t)(MAX_NAME*(n+1)*2));
1842 Rpc_info_size = MAX_NAME*(n+1)*2;
1843 }
1844 else if(Rpc_info_size < MAX_NAME*n*2)
1845 {
1846 free(Rpc_info);
1847 Rpc_info = malloc((size_t)(MAX_NAME*(n+1)*2));
1848 Rpc_info_size = MAX_NAME*(n+1)*2;
1849 }
1850 Rpc_info[0] = '\0';
1851 rpcptr = Rpc_info;
1852 for(i = 0; i < n; i++)
1853 {
1854 rpc = 0;
1855 servp = Service_info_list[i];
1856 if(strstr(servp->serv_name,"/Rpc"))
1857 {
1858 strcpy(aux,servp->serv_name);
1859 if( (ptr = strstr(aux,"/RpcIn")) )
1860 {
1861 *ptr = '\0';
1862 rpc = 1;
1863 if( (ptr = strstr(Rpc_info, aux)) )
1864 {
1865 ptr += (int)strlen(aux);
1866 if(*ptr == '|')
1867 rpc = 2;
1868 }
1869 }
1870 if( (ptr = strstr(aux,"/RpcOut")) )
1871 {
1872 *ptr = '\0';
1873 rpc = 1;
1874 if( (ptr = strstr(Rpc_info, aux)) )
1875 {
1876 ptr += (int)strlen(aux);
1877 if(*ptr == '|')
1878 rpc = 2;
1879 }
1880 }
1881 if(rpc == 1)
1882 {
1883 strcpy(rpcaux, aux);
1884 strcat(rpcaux,"|");
1885 strcat(aux,"/RpcIn");
1886 if( (aux_servp = service_exists(aux)) )
1887 {
1888 strcat(rpcaux, aux_servp->serv_def);
1889 strcat(rpcaux,",");
1890 ptr = strstr(aux,"/RpcIn");
1891 *ptr = '\0';
1892 strcat(aux,"/RpcOut");
1893 if( (aux_servp = service_exists(aux)) )
1894 {
1895 strcat(rpcaux,aux_servp->serv_def);
1896 strcat(rpcaux,"|RPC\n");
1897 strcpy(rpcptr, rpcaux);
1898 rpcptr += (int)strlen(rpcaux);
1899 }
1900 }
1901 }
1902 }
1903 else
1904 {
1905 strcpy(rpcaux, servp->serv_name);
1906 strcat(rpcaux,"|");
1907 strcat(rpcaux,servp->serv_def);
1908 if(servp->serv_id & 0x10000000)
1909 strcat(rpcaux,"|CMD\n");
1910 else
1911 strcat(rpcaux,"|\n");
1912 strcpy(rpcptr, rpcaux);
1913 rpcptr += (int)strlen(rpcaux);
1914 }
1915 }
1916 *rpcptr = '\0';
1917 id[0] = dis_get_conn_id();
1918 id[1] = 0;
1919 dis_selective_update_service(Rpc_id, id);
1920 free(Service_info_list);
1921}
1922
1923void get_rpc_info(int *tag, char **buffer, int *size)
1924{
1925
1926 if(tag){}
1927 *buffer = Rpc_info;
1928 *size = (int)strlen(Rpc_info)+1;
1929}
1930
Note: See TracBrowser for help on using the repository browser.