FACT++  1.0
dns.c
Go to the documentation of this file.
1 /*
2  * DNS (Delphi Name Server) Package implements the name server for the DIM
3  * (Delphi Information Management) system
4  *
5  * Started date : 26-10-92
6  * Last modification : 02-08-94
7  * Written by : C. Gaspar
8  * Adjusted by : G.C. Ballintijn
9  *
10  */
11 
12 #define DNS
13 #include <stdio.h>
14 #include <dim.h>
15 #include <dis.h>
16 
17 #ifndef WIN32
18 #include <netdb.h>
19 #endif
20 /*
21 #define MAX_HASH_ENTRIES 5000
22 */
23 #define MAX_HASH_ENTRIES 25000
24 FILE *foutptr;
25 
26 typedef struct node {
27  struct node *client_next;
28  struct node *client_prev;
29  struct node *next;
30  struct node *prev;
31  int conn_id;
33  struct serv *servp;
34 } NODE;
35 
36 typedef struct red_node {
37  struct red_node *next;
38  struct red_node *prev;
39  int conn_id;
41  struct serv *servp;
42 } RED_NODE;
43 
44 typedef struct serv {
45  struct serv *server_next;
46  struct serv *server_prev;
47  struct serv *next;
48  struct serv *prev;
51  int state;
52  int conn_id;
54  int serv_id;
56 } DNS_SERVICE;
57 
58 typedef struct red_serv {
59  struct red_serv *next;
60  struct red_serv *prev;
63  int state;
64  int conn_id;
66  int serv_id;
69 
72 static int Curr_n_services = 0;
73 static int Curr_n_servers = 0;
74 static int Last_conn_id;
75 /*
76 static int Debug = 2;
77 */
78 static int Debug = 0;
79 
80 static int Timer_q;
82  Rpc_id, wake_up;
83 
84 static char RPC_dummy = 0;
85 static char *Rpc_info = &RPC_dummy;
86 static int Rpc_info_size = 0;
87 
88 static char DNS_accepted_domains[1024] = {0};
89 static 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 
105 static 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  {
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  {
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:
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:
157  printf( " - DIM panic: recv_rout(): Bad switch, exiting...\n");
158  abort();
159  }
160 }
161 
162 static 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 
176 int handle_registration( int conn_id, DIS_DNS_PACKET *packet, int tmout_flag )
177 {
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 
227  (char *) malloc(sizeof(DNS_SERVICE));
228  dll_init( (DLL *) Dns_conns[conn_id].service_head );
230  Dns_conns[conn_id].timr_ent = NULL;
231  Curr_n_servers++;
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);
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  {
262  DNS_accepted_domains[0] = (char)0xFF;
263  }
264  if((DNS_accepted_domains[0] != (char)0xFF) && (strcmp(Dns_conns[conn_id].task_name,"DIS_DNS")))
265  {
266  ptr = DNS_accepted_domains;
267  found = 0;
268  while(*ptr)
269  {
270  ptr1 = strchr(ptr,',');
271  if(ptr1)
272  {
273  *ptr1 = '\0';
274  ptr1++;
275  }
276  else
277  {
278  ptr1 = ptr;
279  ptr1 += (int)strlen(ptr);
280  }
281  if(strstr(Dns_conns[conn_id].node_name,ptr))
282  {
283  found = 1;
284  break;
285  }
286  ptr = ptr1;
287  }
288  if(!found)
289  {
290  dis_packet.type = htovl(DNS_DIS_STOP);
291  dis_packet.size = htovl(DNS_DIS_HEADER);
292  if( !dna_write_nowait(conn_id, &dis_packet, DNS_DIS_HEADER) )
293  {
295  printf(" Stop Server: Couldn't write, releasing %d\n",conn_id);
296  fflush(stdout);
297  }
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)
310  (int)(WATCHDOG_TMOUT_MAX * 1.3), check_validity, conn_id);
311  if(strcmp(Dns_conns[conn_id].task_name,"DIS_DNS"))
312  {
314  }
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 */
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"))
334  printf( " Server %s out of error\n",
335  Dns_conns[conn_id].task_name );
336  fflush(stdout);
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  {
380  printf(" Couldn't write, releasing %d\n",servp->conn_id);
381  fflush(stdout);
382  }
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  {
397 printf(" Service %s already declared by conn %d - %s@%s:%d (PID %d), Redeclared by conn %d - %s@%s:%d (PID %d)(same server) - Closing both conns %d %d\n",
398  servp->serv_name, servp->conn_id,
399  Dns_conns[servp->conn_id].task_name,
400  Dns_conns[servp->conn_id].node_name,
401  Dns_conns[servp->conn_id].port,
402  Dns_conns[servp->conn_id].pid,
403  conn_id,
404  Dns_conns[conn_id].task_name,
405  Dns_conns[conn_id].node_name,
406  Dns_conns[conn_id].port,
407  Dns_conns[conn_id].pid,
408  servp->conn_id, conn_id);
409  fflush(stdout);
410  release_conn(servp->conn_id);
411  release_conn(conn_id);
412 /*
413  update_did = 0;
414 */
415  return(0);
416 
417  }
418  else
419  {
421 
422  if( !dna_write_nowait(conn_id, &dis_packet, DNS_DIS_HEADER) )
423  {
425  printf(" Kill Server: Couldn't write, releasing %d\n",conn_id);
426  fflush(stdout);
427  }
429 printf(" Service %s already declared by conn %d - %s@%s:%d (PID %d), killing server conn %d - %s@%s:%d (PID %d) \n",
430  servp->serv_name, servp->conn_id,
431  Dns_conns[servp->conn_id].task_name,
432  Dns_conns[servp->conn_id].node_name,
433  Dns_conns[servp->conn_id].port,
434  Dns_conns[servp->conn_id].pid,
435  conn_id,
436  Dns_conns[conn_id].task_name,
437  Dns_conns[conn_id].node_name,
438  Dns_conns[conn_id].port,
439  Dns_conns[conn_id].pid);
440  fflush(stdout);
441 
442  release_conn(conn_id);
443 
444  return(0);
445  }
446 #ifdef VMS
447  }
448 #endif
449  }
450  else if( servp->state != -1 )
451  {
452  if( !dll_empty((DLL *) servp->node_head))
453  {
454  /*there are interested clients waiting*/
455  strncpy( servp->serv_def,
456  packet->services[i].service_def,(size_t)MAX_NAME );
457  servp->conn_id = conn_id;
458  servp->state = 1;
459  servp->server_format = vtohl(packet->format);
460  servp->serv_id = vtohl(packet->services[i].service_id);
462  Dns_conns[conn_id].service_head,
463  (DLL *) servp);
465 
466 /*
467  if(n_services == 1)
468 */
469  if(n_services < MAX_REGISTRATION_UNIT)
470  {
471  inform_clients(servp);
472  }
473  continue;
474  }
475  else
476  {
477  /* test if Service is to be removed */
478  service_id = vtohl(packet->services[i].service_id);
479  if((unsigned)service_id & 0x80000000)
480  {
481  dll_remove((DLL *) servp);
482  service_remove(&(servp->next));
483  Curr_n_services--;
484  free(servp);
486  if( dll_empty((DLL *) Dns_conns[conn_id].service_head))
487  {
488  if( Debug )
489  {
491  printf( " Conn %3d : Server %s@%s unregistered All services, releasing it.\n",
492  conn_id, Dns_conns[conn_id].task_name,
493  Dns_conns[conn_id].node_name );
494  fflush(stdout);
495  }
496  release_conn(conn_id);
497  return(0);
498  }
499  continue;
500  }
501  }
502  }
503  else
504  {
505  servp->state = 1;
507 /*
508  if(n_services == 1)
509 */
510  if(n_services < MAX_REGISTRATION_UNIT)
511  {
512  if( !dll_empty((DLL *) servp->node_head) )
513  {
514  inform_clients( servp );
515  }
516  }
517  continue;
518  }
519 
520  }
521  if(!(servp = service_exists(packet->services[i].service_name)))
522  {
523  servp = (DNS_SERVICE *)malloc(sizeof(DNS_SERVICE));
524  if(name_too_long)
525  {
526  if(strstr(packet->services[i].service_name,"/CLIENT_LIST"))
527  {
528  strncpy(Dns_conns[conn_id].long_task_name, packet->services[i].service_name,
529  (size_t)MAX_NAME);
530  ptrt = strstr(Dns_conns[conn_id].long_task_name,"/CLIENT_LIST");
531  *ptrt = '\0';
532  }
533  }
534  strncpy( servp->serv_name,
535  packet->services[i].service_name,
536  (size_t)MAX_NAME );
537  strncpy( servp->serv_def,
538  packet->services[i].service_def,
539  (size_t)MAX_NAME );
540  servp->state = 1;
541  servp->conn_id = conn_id;
542  servp->server_format = vtohl(packet->format);
543  servp->serv_id = vtohl(packet->services[i].service_id);
544  dll_insert_queue( (DLL *)
545  Dns_conns[conn_id].service_head,
546  (DLL *) servp );
548  service_insert( &(servp->next) );
549  servp->node_head = (RED_NODE *) malloc(sizeof(NODE));
550  dll_init( (DLL *) servp->node_head );
551  Curr_n_services++;
552  }
553  }
554  if(update_did)
555  do_update_did(conn_id);
556  if( Debug )
557  {
558  if(vtohl(packet->n_services) != 0)
559  {
561  printf( " Conn %3d : Server %s@%s (PID %d) registered %d services\n",
562  conn_id, Dns_conns[conn_id].task_name,
563  Dns_conns[conn_id].node_name,
564  Dns_conns[conn_id].pid,
565  vtohl(packet->n_services) );
566  fflush(stdout);
567  }
568  }
569 
570  return(1);
571 }
572 
574 {
575  int i;
576  void do_update_did();
577 
578  for(i = 0; i< Curr_N_Conns; i++)
579  {
580  if(Dns_conns[i].src_type == SRC_DIS)
581  {
582  do_update_did(i);
583  }
584  }
585 }
586 
588 {
589  int n_services, old_n_services;
590 
591  n_services = Dns_conns[conn_id].n_services;
592 /*
593  if(Dns_conns[conn_id].n_services)
594  {
595 */
596  old_n_services = Dns_conns[conn_id].old_n_services;
597  if(old_n_services != n_services)
598  {
600  if((old_n_services <= 0) || (n_services == 0) || (n_services == -1))
604  }
605 /*
606  }
607 */
608 }
609 
611 {
612  int time_diff;
613  DNS_DIS_PACKET dis_packet;
614  void set_in_error();
615 
616  if(Dns_conns[conn_id].validity < 0)
617  {
618  /* timeout reached kill all services and connection */
619  if(Dns_conns[conn_id].n_services != -1)
620  {
622  printf(" Server %s (%s@%s) has been set in error\n",
623  Dns_conns[conn_id].task_name, Net_conns[conn_id].task, Net_conns[conn_id].node);
624  fflush(stdout);
625  set_in_error(conn_id);
626  return;
627  }
628 /*
629  Dns_conns[conn_id].validity = -Dns_conns[conn_id].validity;
630 */
631  }
632  time_diff = (int)time(NULL) - Dns_conns[conn_id].validity;
633  if(time_diff > (int)(WATCHDOG_TMOUT_MAX*1.2))
634  {
635  /* send register signal */
636  dis_packet.type = htovl(DNS_DIS_REGISTER);
637  dis_packet.size = htovl(DNS_DIS_HEADER);
638  if(Debug)
639  {
641  printf(" Conn %3d : Server %s@%s Registration Requested\n",
642  conn_id, Net_conns[conn_id].task, Net_conns[conn_id].node);
643  fflush(stdout);
644  }
645 /* moved from dna_write to dna_write_nowait in 14/10/2008 */
646  if( !dna_write_nowait(conn_id, &dis_packet, DNS_DIS_HEADER) )
647  {
649  printf(" Server Validity: Couldn't write, releasing Conn %3d : Server %s@%s\n",conn_id,
650  Net_conns[conn_id].task, Net_conns[conn_id].node);
651  fflush(stdout);
652  release_conn(conn_id);
653  }
654  else
656  }
657 }
658 
659 
661 {
663  NODE *nodep;
664  RED_NODE *red_nodep;
665  int i, service_id;
666  DNS_DIC_PACKET dic_packet;
667  SERVICE_REG *serv_regp;
668  void service_insert();
669  void service_remove();
670  void tcpip_get_addresses();
671  char *ptr, *ptr1;
672  int found;
673 
674  serv_regp = (SERVICE_REG *)(&(packet->service));
675  if(Debug)
676  {
678  printf(" Conn %3d : Client %s@%s requested %s\n",
679  conn_id, Net_conns[conn_id].task, Net_conns[conn_id].node,
680  serv_regp->service_name);
681  fflush(stdout);
682  }
683 
684  if(DNS_accepted_nodes[0] == 0)
685  {
687  DNS_accepted_nodes[0] = (char)0xFF;
688  }
689  if(DNS_accepted_nodes[0] != (char)0xFF)
690  {
691  ptr = DNS_accepted_nodes;
692  found = 0;
693  while(*ptr)
694  {
695  ptr1 = strchr(ptr,',');
696  if(ptr1)
697  {
698  *ptr1 = '\0';
699  ptr1++;
700  }
701  else
702  {
703  ptr1 = ptr;
704  ptr1 += (int)strlen(ptr);
705  }
706  if(strstr(Net_conns[conn_id].node,ptr))
707  {
708  found = 1;
709  break;
710  }
711  ptr = ptr1;
712  }
713  if(!found)
714  {
715  dic_packet.service_id = serv_regp->service_id;
716  dic_packet.node_name[0] = (char)0xFF;
717  dic_packet.task_name[0] = 0;
718  dic_packet.node_addr[0] = 0;
719  dic_packet.pid = 0;
720  dic_packet.size = htovl(DNS_DIC_HEADER);
722  printf(" Connection from %s refused, stopping client pid=%s\n",
723  Net_conns[conn_id].node,
724  Net_conns[conn_id].task);
725  fflush(stdout);
726  if( !dna_write_nowait(conn_id, &dic_packet, DNS_DIC_HEADER) )
727  {
729  printf(" Stop Client: Couldn't write, releasing Conn %3d : Client %s@%s\n",conn_id,
730  Net_conns[conn_id].task,
731  Net_conns[conn_id].node);
732  fflush(stdout);
733  }
734  release_conn(conn_id);
735 
736  return 0;
737  }
738  }
739 
740  service_id = vtohl(serv_regp->service_id);
741  if( service_id == -1 ) /* remove service */
742  {
743  if(Debug)
744  {
745  printf("\tRemoving Request\n");
746  fflush(stdout);
747  }
748  if( (servp = service_exists(serv_regp->service_name)) )
749  {
750  red_nodep = servp->node_head;
751  while( (red_nodep =
753  (DLL *) servp->node_head,
754  (DLL *) red_nodep)) )
755  {
756  if( red_nodep->conn_id == conn_id )
757  {
758  dll_remove((DLL *) red_nodep);
759  ptr = (char *)red_nodep - (2 * sizeof(void *));
760  nodep = (NODE *)ptr;
761  dll_remove((DLL *) nodep);
762  red_nodep = red_nodep->prev;
763  free(nodep);
764  break;
765  }
766  }
767  if(( dll_empty((DLL *) servp->node_head) ) && (servp->state == 0))
768  {
769  if(Debug)
770  {
771  printf("\tand Removing Service\n");
772  fflush(stdout);
773  }
774  service_remove(&(servp->next));
775  Curr_n_services--;
776  free(servp);
777  }
778  }
779  return(0);
780  }
781  if( (unsigned)service_id & 0x80000000 ) /* remove service */
782  {
783  service_id &= 0x7fffffff;
784  if(Debug)
785  {
786  printf("\tRemoving Request\n");
787  fflush(stdout);
788  }
789  if( (servp = service_exists(serv_regp->service_name)) )
790  {
791  red_nodep = servp->node_head;
792  while( (red_nodep =
794  (DLL *) servp->node_head,
795  (DLL *) red_nodep)) )
796  {
797  if(( red_nodep->conn_id == conn_id ) &&
798  ( red_nodep->service_id == service_id ) )
799  {
800  dll_remove((DLL *) red_nodep);
801  ptr = (char *)red_nodep - (2 * sizeof(void *));
802  nodep = (NODE *)ptr;
803  dll_remove((DLL *) nodep);
804  red_nodep = red_nodep->prev;
805  free(nodep);
806  break;
807  }
808  }
809  if(( dll_empty((DLL *) servp->node_head) ) && (servp->state == 0))
810  {
811  if(Debug)
812  {
813  printf("\tand Removing Service\n");
814  fflush(stdout);
815  }
816  service_remove(&(servp->next));
817  Curr_n_services--;
818  free(servp);
819  }
820  }
821  return(0);
822  }
823  /* Is already in v.format */
824  dic_packet.service_id = serv_regp->service_id;
825  dic_packet.node_name[0] = 0;
826  dic_packet.task_name[0] = 0;
827  dic_packet.node_addr[0] = 0;
828  dic_packet.pid = 0;
829  dic_packet.size = htovl(DNS_DIC_HEADER);
830  if( Dns_conns[conn_id].src_type == SRC_NONE )
832  if( !(servp = service_exists(serv_regp->service_name)) )
833  {
834  if(Debug)
835  {
836  printf("\tService does not exist, queueing request\n");
837  fflush(stdout);
838  }
839  if( !Dns_conns[conn_id].node_head )
840  {
843  malloc(sizeof(NODE));
844  dll_init( (DLL *) Dns_conns[conn_id].node_head );
845  }
846  servp = (DNS_SERVICE *) malloc(sizeof(DNS_SERVICE));
847  strncpy( servp->serv_name, serv_regp->service_name, (size_t)MAX_NAME );
848  servp->serv_def[0] = '\0';
849  servp->state = 0;
850  servp->conn_id = 0;
851  service_insert(&(servp->next));
852  Curr_n_services++;
853  servp->node_head = (RED_NODE *)malloc(sizeof(NODE));
854  dll_init( (DLL *) servp->node_head );
855  nodep = (NODE *)malloc(sizeof(NODE));
856  nodep->conn_id = conn_id;
857  nodep->service_id = service_id;
858  nodep->servp = servp;
859  dll_insert_queue((DLL *) Dns_conns[conn_id].node_head,
860  (DLL *) nodep);
861  dll_insert_queue((DLL *) servp->node_head,
862  (DLL *) &(nodep->next));
863  }
864  else
865  {
866  if( servp->state == 1 )
867  {
868 #ifdef VMS
869  if(servp->server_format & MY_OS9)
870  {
871  dna_test_write(servp->conn_id);
872  }
873 #endif
875  strcpy( dic_packet.node_name,
876  Dns_conns[servp->conn_id].node_name );
877  strcpy( dic_packet.task_name,
878  Dns_conns[servp->conn_id].task_name );
879  for(i = 0; i < 4; i++)
880  dic_packet.node_addr[i] =
881  Dns_conns[servp->conn_id].node_addr[i];
882  dic_packet.port = htovl(Dns_conns[servp->conn_id].port);
883  dic_packet.pid = htovl(Dns_conns[servp->conn_id].pid);
884  dic_packet.protocol = htovl(Dns_conns[servp->conn_id].protocol);
885  dic_packet.format = htovl(servp->server_format);
886  strcpy( dic_packet.service_def, servp->serv_def );
887  if(Debug)
888  {
889  printf("\tService exists in %s@%s, port = %d\n",
890  dic_packet.task_name, dic_packet.node_name,
891  dic_packet.port);
892  fflush(stdout);
893  }
894  }
895  else
896  {
897  if(Debug)
898  {
899  if(servp->state == -1)
900  {
901  printf("\tService exists in BAD state, queueing request\n");
902  fflush(stdout);
903  }
904  else
905  {
906  printf("\tService does not exist (other client(s) waiting), queueing request\n");
907  fflush(stdout);
908  }
909  }
910  if(!(NODE *)Dns_conns[conn_id].node_head )
911  {
914  (char *) malloc(sizeof(NODE));
915  dll_init((DLL *)Dns_conns[conn_id].node_head);
916  }
917  nodep = (NODE *)malloc(sizeof(NODE));
918  nodep->conn_id = conn_id;
919  nodep->service_id = service_id;
920  nodep->servp = servp;
921  dll_insert_queue((DLL *) Dns_conns[conn_id].node_head,
922  (DLL *) nodep);
923  dll_insert_queue((DLL *) servp->node_head,
924  (DLL *) &(nodep->next));
925  }
926  }
927 /* Should it be dna_write_nowait? 16/9/2008 */
928 /* moved from dna_write to dna_write_nowait in 14/10/2008 */
929  if( !dna_write_nowait(conn_id, &dic_packet, DNS_DIC_HEADER) )
930  {
932  printf(" Client Request: Couldn't write, releasing Conn %3d : Client %s@%s\n",conn_id,
933  Net_conns[conn_id].task,
934  Net_conns[conn_id].node);
935  fflush(stdout);
936  release_conn(conn_id);
937  }
938 
939  return(1);
940 }
941 
943 {
945  int n_informed = 0;
946  static DNS_SERVICE *prev_servp = (DNS_SERVICE *)0;
947  void inform_clients();
948 
949  DISABLE_AST
950  if(!Dns_conns[conn_id].service_head)
951  {
952  prev_servp = (DNS_SERVICE *)0;
953  ENABLE_AST
954  return;
955  }
956  if(prev_servp)
957  servp = prev_servp;
958  else
959  servp = (DNS_SERVICE *)Dns_conns[conn_id].service_head;
960  while( (servp = (DNS_SERVICE *) dll_get_next(
961  (DLL *) Dns_conns[conn_id].service_head,
962  (DLL *) servp)) )
963  {
964  if( servp->state != -1 )
965  {
966  if( !dll_empty((DLL *) servp->node_head))
967  {
968  inform_clients(servp);
969  n_informed++;
970  if(n_informed == 1000)
971  {
972  dtq_start_timer(0, do_inform_clients, conn_id);
973  ENABLE_AST
974  return;
975  }
976  }
977  }
978  }
979  prev_servp = (DNS_SERVICE *)0;
980  ENABLE_AST
981 }
982 
983 
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  {
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 /*
1022 release_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
1045 static release_client(int conn_id)
1046 {
1047 char *ptr_task;
1048 char *ptr_node;
1049 int 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  {
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 
1077 static void release_conn(int conn_id)
1078 {
1079  DNS_SERVICE *servp, *old_servp;
1080  NODE *nodep, *old_nodep;
1081  void service_remove();
1082 
1083  servp = (DNS_SERVICE *)Dns_conns[conn_id].service_head;
1084  nodep = (NODE *)Dns_conns[conn_id].node_head;
1085  if(( Dns_conns[conn_id].src_type == SRC_DIS ) || (servp))
1086  {
1087  if( Debug )
1088  {
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  {
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  {
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);
1147  dna_close(conn_id);
1148  }
1149  else if((Dns_conns[conn_id].src_type == SRC_DIC) || (nodep))
1150  {
1151  if(Debug)
1152  {
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);
1180  }
1182  dna_close(conn_id);
1183  }
1184  else
1185  {
1186  if(Debug)
1187  {
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 
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 
1216 void 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 
1239 void send_dns_server_info(int conn_id, int **bufp, int *size)
1240 {
1241  static int curr_allocated_size = 0;
1242  static DNS_DID *dns_info_buffer;
1243  DNS_SERVICE *servp;
1244  DNS_SERVER_INFO *dns_server_info;
1245  DNS_SERVICE_INFO *dns_service_info;
1246  DNS_CONNECTION *connp;
1247  int max_size;
1248  int n_services;
1249 
1250  DISABLE_AST
1251  connp = &Dns_conns[conn_id];
1252  if(connp->src_type != SRC_DIS)
1253  {
1254  ENABLE_AST
1255  return;
1256  }
1257  n_services = connp->n_services;
1258  if(n_services == -1)
1259  n_services = 0;
1260  max_size = (int)sizeof(DNS_SERVER_INFO) +
1261  n_services * (int)sizeof(DNS_SERVICE_INFO);
1262  if(!curr_allocated_size)
1263  {
1264  dns_info_buffer = (DNS_DID *)malloc((size_t)max_size);
1265  curr_allocated_size = max_size;
1266  }
1267  else if (max_size > curr_allocated_size)
1268  {
1269  free(dns_info_buffer);
1270  dns_info_buffer = (DNS_DID *)malloc((size_t)max_size);
1271  curr_allocated_size = max_size;
1272  }
1273  dns_server_info = &dns_info_buffer->server;
1274  dns_service_info = dns_info_buffer->services;
1275  strncpy(dns_server_info->task, connp->task_name, (size_t)(MAX_TASK_NAME-4));
1276  strncpy(dns_server_info->node, connp->node_name, (size_t)MAX_NODE_NAME);
1277  dns_server_info->pid = htovl(connp->pid);
1278  dns_server_info->n_services = htovl(connp->n_services);
1279  servp = (DNS_SERVICE *)connp->service_head;
1280  while( (servp = (DNS_SERVICE *) dll_get_next((DLL *) connp->service_head,
1281  (DLL *) servp)) )
1282  {
1283  strncpy(dns_service_info->name, servp->serv_name, (size_t)MAX_NAME);
1284  dns_service_info->status = htovl(1);
1285  if(servp->serv_id & 0x10000000)
1286  dns_service_info->type = htovl(1);
1287  else
1288  dns_service_info->type = htovl(0);
1289  dns_service_info++;
1290  }
1291  *bufp = (int *)dns_info_buffer;
1292  *size = max_size;
1293  ENABLE_AST
1294 }
1295 
1296 void get_new_dns_server_info(int *tag, int **bufp, int *size, int *first_time)
1297 {
1298  static int curr_allocated_size = 0;
1299  static char *info_buffer;
1300  static int *pid_buffer, pid_size;
1301  int pid_index = 0;
1302  DNS_CONNECTION *connp;
1303  int i, max_size, max_pid_size/*, j, n*/;
1304  int n_server = 0;
1305  char /*aux[MAX_NAME], *ptr, */ server[MAX_NAME], *info_buffer_ptr;
1306 /*
1307  DNS_SERVICE *servp;
1308  int find_services();
1309 */
1310 
1311  DISABLE_AST
1312  if(tag){}
1313  for( i = 0; i< Curr_N_Conns; i++ )
1314  {
1315  if( Dns_conns[i].src_type == SRC_DIS )
1316  {
1317  n_server++;
1318  }
1319  }
1320  max_size = ((int)sizeof(DNS_SERVER_INFO) + MAX_TASK_NAME) * n_server;
1321  max_pid_size = (int)sizeof(int) * n_server;
1322  if(!curr_allocated_size)
1323  {
1324  info_buffer = (char *)malloc((size_t)max_size);
1325  curr_allocated_size = max_size;
1326  pid_buffer = (int *)malloc((size_t)max_pid_size);
1327  }
1328  else if (max_size > curr_allocated_size)
1329  {
1330  free(info_buffer);
1331  info_buffer = (char *)malloc((size_t)max_size);
1332  curr_allocated_size = max_size;
1333  free(pid_buffer);
1334  pid_buffer = (int *)malloc((size_t)max_pid_size);
1335  }
1336  info_buffer[0] = '\0';
1337  pid_buffer[0] = 0;
1338 
1339  info_buffer_ptr = info_buffer;
1340  if(*first_time)
1341  {
1342  for( i = 0; i< Curr_N_Conns; i++ )
1343  {
1344  if( Dns_conns[i].src_type == SRC_DIS )
1345  {
1346  connp = &Dns_conns[i];
1347 /*
1348  if((int)strlen(connp->task_name) == MAX_TASK_NAME-4-1)
1349  {
1350  strcpy(aux,connp->task_name);
1351  strcat(aux,"--CLIENT_LIST");
1352  n = find_services(aux);
1353  for(j = 0; j < n; j++)
1354  {
1355  servp = Service_info_list[j];
1356  if(i == servp->conn_id)
1357  {
1358  strcpy(aux,servp->serv_name);
1359  ptr = strstr(aux,"/CLIENT_LIST");
1360  if(ptr)
1361  *ptr = '\0';
1362  break;
1363  }
1364  }
1365  free(Service_info_list);
1366  strcpy(server, aux);
1367  }
1368  else
1369  {
1370 */
1371  strcpy(server, connp->long_task_name);
1372 /*
1373  }
1374 */
1375  strcat(server,"@");
1376  strcat(server, connp->node_name);
1377  strcat(server,"|");
1378  strcpy(info_buffer_ptr, server);
1379  info_buffer_ptr += (int)strlen(server);
1380  pid_buffer[pid_index] = connp->pid;
1381  pid_index++;
1382  }
1383  }
1384  }
1385  else
1386  {
1387  connp = &Dns_conns[Last_conn_id];
1388  if(connp->n_services > 0)
1389  strcat(info_buffer, "+");
1390  else if(connp->n_services == -1)
1391  strcat(info_buffer, "!");
1392  else
1393  strcat(info_buffer, "-");
1394  strcat(info_buffer, connp->long_task_name);
1395  strcat(info_buffer,"@");
1396  strcat(info_buffer, connp->node_name);
1397  strcat(info_buffer,"|");
1398  pid_buffer[pid_index] = connp->pid;
1399  pid_index++;
1400  }
1401  info_buffer[(int)strlen(info_buffer) - 1] = '\0';
1402  info_buffer_ptr = &info_buffer[(int)strlen(info_buffer)+1];
1403  pid_size = 0;
1404  for(i = 0; i < pid_index; i++)
1405  {
1406  if(i != (pid_index -1))
1407  sprintf(server, "%d|",pid_buffer[i]);
1408  else
1409  sprintf(server, "%d",pid_buffer[i]);
1410  strcpy(info_buffer_ptr, server);
1411  info_buffer_ptr += (int)strlen(server);
1412  pid_size += (int)strlen(server);
1413  }
1414  *bufp = (int *)info_buffer;
1415  *size = (int)strlen(info_buffer)+1+pid_size+1;
1416  ENABLE_AST
1417 }
1418 
1419 int 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  }
1440  dim_set_listen_backlog(1024);
1443  dim_set_read_buffer_size(32768);
1444  dim_init();
1446  service_init();
1447  Timer_q = dtq_create();
1448  get_node_name(node);
1450  printf(" DNS version %d starting up on %s\n",DIM_VERSION_NUMBER, node);
1451  fflush(stdout);
1452 
1453  Server_new_info_id =(int) dis_add_service( "DIS_DNS/SERVER_LIST", "C", 0, 0,
1455  Server_info_id = (int)dis_add_service( "DIS_DNS/SERVER_INFO", 0, 0, 0,
1456  get_dns_server_info, 0 );
1457  dis_add_cmnd( "DIS_DNS/PRINT_STATS", 0, print_stats, 0 );
1458  dis_add_cmnd( "DIS_DNS/DEBUG_ON", 0, set_debug_on, 0 );
1459  dis_add_cmnd( "DIS_DNS/DEBUG_OFF", 0, set_debug_off, 0 );
1460  dis_add_cmnd( "DIS_DNS/KILL_SERVERS", "I", kill_servers, 0 );
1461  dis_add_cmnd( "DIS_DNS/PRINT_HASH_TABLE", 0, print_hash_table, 0 );
1462  dis_add_cmnd( "DIS_DNS/SERVICE_INFO/RpcIn", "C", set_rpc_info, 0 );
1463  Rpc_id = (int)dis_add_service( "DIS_DNS/SERVICE_INFO/RpcOut", "C", 0, 0,
1464  get_rpc_info, 0 );
1465  dns_port = get_dns_port_number();
1466  if( !dna_open_server(DNS_TASK, recv_rout, &protocol, &dns_port, error_handler) )
1467  return(0);
1468 
1469  id = dis_start_serving("DIS_DNS");
1470  dis_dns_packet = (DIS_DNS_PACKET *) id_get_ptr(id, SRC_DIS);
1471  id_free(id, SRC_DIS);
1472  conn_id = conn_get();
1473  handle_registration(conn_id, dis_dns_packet, 0);
1474  dtq_add_entry(Timer_q, 5, update_did, 0xded0000);
1475  while(1)
1476  {
1477 #ifdef VMS
1478  sys$hiber();
1479 #else
1480  wake_up = FALSE;
1481  while( !wake_up )
1482  {
1483  dim_wait();
1484  }
1485 #endif
1486  for( i = 0; i< Curr_N_Conns; i++ )
1487  {
1488  if( Dns_conns[i].src_type == SRC_DIS )
1489  {
1490  send_dns_server_info( i, &bufp, &size );
1491  dis_send_service( Server_info_id, bufp, size );
1492  }
1493  }
1494  }
1495  return(1);
1496 }
1497 
1498 
1500 {
1501  int i;
1502  int n_conns = 0;
1503  int n_services = 0;
1504  int n_servers = 0;
1505  int n_clients = 0;
1506 
1508  printf(" Connection Statistics :\n");
1509  for(i = 0; i< Curr_N_Conns; i++)
1510  {
1511  switch(Dns_conns[i].src_type)
1512  {
1513  case SRC_DIS :
1514  printf("%d - Server %s@%s (PID %d) %d services\n",
1515  i, Dns_conns[i].task_name,
1516  Dns_conns[i].node_name,
1517  Dns_conns[i].pid, Dns_conns[i].n_services);
1518  fflush(stdout);
1519  n_services += Dns_conns[i].n_services;
1520  n_servers++;
1521  n_conns++;
1522  break;
1523  case SRC_DIC :
1524  printf("%d - Client %s@%s\n",
1525  i, Net_conns[i].task, Net_conns[i].node);
1526  fflush(stdout);
1527  n_conns++;
1528  n_clients++;
1529  break;
1530  default :
1531  if(Dna_conns[i].busy)
1532  {
1533  if(Net_conns[i].task[0] && Net_conns[i].node[0])
1534  printf("%d - Undefined %s@%s\n",
1535  i, Net_conns[i].task,
1536  Net_conns[i].node);
1537  else
1538  printf("%d - Undefined\n", i);
1539  fflush(stdout);
1540  n_conns++;
1541  }
1542  else
1543  {
1544  printf("%d - Empty\n", i);
1545  fflush(stdout);
1546  }
1547  }
1548  }
1549  printf("Number of Connections = %d : %d servers, %d clients\n", n_conns,
1550  n_servers, n_clients);
1551  printf("Number of Services = %d\n", n_services);
1552  fflush(stdout);
1553 }
1554 
1555 
1557 {
1558  Debug = 1;
1559 }
1560 
1561 
1563 {
1564  Debug = 0;
1565 }
1566 
1567 
1568 void kill_servers(int *tag, int *code, int *size)
1569 {
1570  int i;
1571  DNS_DIS_PACKET dis_packet;
1572  int soft_code = 0, soft_size = 0;
1573  int type;
1574 
1575  if(tag){}
1576  if(size)
1577  {
1578  soft_size = *size;
1579  if(code)
1580  {
1581  soft_code = *code;
1582  }
1583  }
1584  for(i = 0; i< Curr_N_Conns; i++)
1585  {
1586  if(Dns_conns[i].src_type == SRC_DIS)
1587  {
1588  if(!strcmp(Dns_conns[i].task_name,"DIS_DNS"))
1589  continue;
1590  fflush(stdout);
1591  type = DNS_DIS_EXIT;
1592  if(soft_size)
1593  {
1594  type = DNS_DIS_SOFT_EXIT;
1595  type |= (soft_code << (int)16) & (int)0xFFFF0000;
1597  printf(" Killing server %s@%s with exit code %d\n",
1598  Dns_conns[i].task_name, Dns_conns[i].node_name, soft_code);
1599  }
1600  else
1601  {
1603  printf(" Killing server %s@%s\n",
1604  Dns_conns[i].task_name, Dns_conns[i].node_name);
1605  }
1606  dis_packet.type = htovl(type);
1607  dis_packet.size = htovl(DNS_DIS_HEADER);
1608  if( !dna_write_nowait(i, &dis_packet, DNS_DIS_HEADER) )
1609  {
1611  printf(" Kill Server: Couldn't write, releasing %d\n",i);
1612  fflush(stdout);
1613  release_conn(i);
1614  }
1615  }
1616  }
1617 }
1618 
1619 
1621 {
1622  int i;
1623 
1624  for( i = 0; i < MAX_HASH_ENTRIES; i++ ) {
1625  Service_hash_table[i] = (RED_DNS_SERVICE *) malloc(sizeof(RED_DNS_SERVICE));
1626  dll_init((DLL *) Service_hash_table[i]);
1627  }
1628 }
1629 
1630 
1632 {
1633  int index;
1634 
1635  index = HashFunction(servp->serv_name, MAX_HASH_ENTRIES);
1636  dll_insert_queue((DLL *) Service_hash_table[index],
1637  (DLL *) servp);
1638 }
1639 
1640 
1642 {
1643  if( servp->node_head )
1644  free( servp->node_head );
1645  dll_remove( (DLL *) servp );
1646 }
1647 
1648 
1650 {
1651  int index;
1653  char *ptr;
1654 
1655  index = HashFunction(name, MAX_HASH_ENTRIES);
1656  if( (servp = (RED_DNS_SERVICE *) dll_search(
1657  (DLL *) Service_hash_table[index],
1658  name, (int)strlen(name)+1)) )
1659  {
1660  ptr = (char *)servp - (2 * sizeof(void *));
1661  return((DNS_SERVICE *)ptr);
1662  }
1663 
1664  return((DNS_SERVICE *)0);
1665 }
1666 
1668 {
1669  int i;
1671  int n_entries, max_entry_index = 0;
1672  int max_entries = 0;
1673 
1674 #ifdef VMS
1675  if( ( foutptr = fopen( "scratch$week:[cp_operator]dim_dns.log", "w" )
1676  ) == (FILE *)0 )
1677  {
1678  printf("Cannot open: scratch$week:[cp_operator]dim_dns.log for writing\n");
1679  fflush(stdout);
1680  return;
1681  }
1682 #endif
1683 
1684  for( i = 0; i < MAX_HASH_ENTRIES; i++ )
1685  {
1686  n_entries = 0;
1687 #ifdef VMS
1688  fprintf(foutptr,"HASH[%d] : \n",i);
1689 #endif
1690  servp = Service_hash_table[i];
1691  while( (servp = (RED_DNS_SERVICE *) dll_get_next(
1692  (DLL *) Service_hash_table[i],
1693  (DLL *) servp)) )
1694  {
1695 #ifdef VMS
1696  fprintf(foutptr,"%s\n",servp->serv_name);
1697 #endif
1698  n_entries++;
1699  }
1700 #ifdef VMS
1701  fprintf(foutptr,"\n\n");
1702 #endif
1703  if(n_entries != 0)
1704  printf("HASH[%d] - %d entries\n", i, n_entries);
1705  if(n_entries > max_entries)
1706  {
1707  max_entries = n_entries;
1708  max_entry_index = i;
1709  }
1710  }
1711 #ifdef VMS
1712  fclose(foutptr);
1713 #endif
1714  printf("Maximum : HASH[%d] - %d entries\n", max_entry_index, max_entries);
1715  fflush(stdout);
1716 }
1717 
1718 int find_services(char *wild_name)
1719 {
1720 
1721  int i;
1723  DNS_SERVICE *servp1;
1724  char tmp[MAX_NAME], *ptr, *ptr1, *dptr, *dptr1;
1725  int match, count = 0;
1726 
1727  Service_info_list = (DNS_SERVICE **)
1728  malloc((size_t)(Curr_n_services*(int)sizeof(DNS_SERVICE *)));
1729 
1730  if(!strchr(wild_name, '*'))
1731  {
1732  servp1 = service_exists(wild_name);
1733  if(servp1)
1734  {
1735  if(servp1->state == 1)
1736  {
1737  Service_info_list[count] = (DNS_SERVICE *)servp1;
1738  count++;
1739  return 1;
1740  }
1741  }
1742  return 0;
1743  }
1744  for( i = 0; i < MAX_HASH_ENTRIES; i++ )
1745  {
1746  servp = Service_hash_table[i];
1747  while( (servp = (RED_DNS_SERVICE *) dll_get_next(
1748  (DLL *) Service_hash_table[i],
1749  (DLL *) servp)) )
1750  {
1751  ptr = wild_name;
1752  dptr = servp->serv_name;
1753  match = 1;
1754 
1755  while( (ptr1 = strchr(ptr,'*')) )
1756  {
1757  if(ptr1 == ptr)
1758  {
1759  ptr++;
1760  if(!*ptr)
1761  {
1762  dptr = ptr;
1763  break;
1764  }
1765  strcpy(tmp,ptr);
1766  if( (ptr1 = strchr(ptr,'*')) )
1767  {
1768  tmp[ptr1-ptr] = '\0';
1769  }
1770  if( (dptr1 = strstr(dptr, tmp)) )
1771  {
1772  if(!ptr1)
1773  {
1774  dptr = dptr1;
1775  break;
1776  }
1777  dptr1 += (int)strlen(tmp);
1778  ptr = ptr1;
1779  dptr = dptr1;
1780  }
1781  else
1782  {
1783  match = 0;
1784  break;
1785  }
1786  }
1787  else
1788  {
1789  strcpy(tmp,ptr);
1790  tmp[ptr1-ptr] = '\0';
1791  if(!strncmp(dptr, tmp, strlen(tmp)))
1792  {
1793  dptr += (int)strlen(tmp);
1794  ptr = ptr1;
1795  }
1796  else
1797  {
1798  match = 0;
1799  break;
1800  }
1801  }
1802  }
1803  if(strcmp(dptr, ptr))
1804  {
1805  strcpy(tmp,ptr);
1806  strcat(tmp,"/RpcIn");
1807  if(strcmp(dptr, tmp))
1808  match = 0;
1809  }
1810  if(match)
1811  {
1812  if(servp->state == 1)
1813  {
1814  ptr = (char *)servp - (2 * sizeof(void *));
1815  Service_info_list[count] = (DNS_SERVICE *)ptr;
1816  count++;
1817  }
1818  }
1819  }
1820  }
1821  return(count);
1822 }
1823 
1824 void set_rpc_info(int *tag, char *buffer, int *size)
1825 {
1826  char aux[MAX_NAME], rpcaux[MAX_NAME+32], *ptr, *rpcptr;
1827  int i, n, rpc, id[2], conn_id;
1828  DNS_SERVICE *servp, *aux_servp;
1829 
1830  if(size){}
1831  if(tag){}
1832  if(Debug)
1833  {
1835  conn_id = dis_get_conn_id();
1836  printf(" Got Browse Request <%s> from conn: %d %s@%s\n", buffer, conn_id,
1837  Net_conns[conn_id].task,Net_conns[conn_id].node);
1838  }
1839  n = find_services(buffer);
1840  if(Debug)
1841  {
1843  conn_id = dis_get_conn_id();
1844  printf(" Browse Request <%s> found %d services\n", buffer, n);
1845  }
1846  if(!Rpc_info_size)
1847  {
1848  Rpc_info = malloc((size_t)(MAX_NAME*(n+1)*2));
1849  Rpc_info_size = MAX_NAME*(n+1)*2;
1850  }
1851  else if(Rpc_info_size < MAX_NAME*n*2)
1852  {
1853  free(Rpc_info);
1854  Rpc_info = malloc((size_t)(MAX_NAME*(n+1)*2));
1855  Rpc_info_size = MAX_NAME*(n+1)*2;
1856  }
1857  Rpc_info[0] = '\0';
1858  rpcptr = Rpc_info;
1859  for(i = 0; i < n; i++)
1860  {
1861  rpc = 0;
1862  servp = Service_info_list[i];
1863  if(strstr(servp->serv_name,"/Rpc"))
1864  {
1865  strcpy(aux,servp->serv_name);
1866  if( (ptr = strstr(aux,"/RpcIn")) )
1867  {
1868  *ptr = '\0';
1869  rpc = 1;
1870  if( (ptr = strstr(Rpc_info, aux)) )
1871  {
1872  ptr += (int)strlen(aux);
1873  if(*ptr == '|')
1874  rpc = 2;
1875  }
1876  }
1877  if( (ptr = strstr(aux,"/RpcOut")) )
1878  {
1879  *ptr = '\0';
1880  rpc = 1;
1881  if( (ptr = strstr(Rpc_info, aux)) )
1882  {
1883  ptr += (int)strlen(aux);
1884  if(*ptr == '|')
1885  rpc = 2;
1886  }
1887  }
1888  if(rpc == 1)
1889  {
1890  strcpy(rpcaux, aux);
1891  strcat(rpcaux,"|");
1892  strcat(aux,"/RpcIn");
1893  if( (aux_servp = service_exists(aux)) )
1894  {
1895  strcat(rpcaux, aux_servp->serv_def);
1896  strcat(rpcaux,",");
1897  ptr = strstr(aux,"/RpcIn");
1898  *ptr = '\0';
1899  strcat(aux,"/RpcOut");
1900  if( (aux_servp = service_exists(aux)) )
1901  {
1902  strcat(rpcaux,aux_servp->serv_def);
1903  strcat(rpcaux,"|RPC\n");
1904  strcpy(rpcptr, rpcaux);
1905  rpcptr += (int)strlen(rpcaux);
1906  }
1907  }
1908  }
1909  }
1910  else
1911  {
1912  strcpy(rpcaux, servp->serv_name);
1913  strcat(rpcaux,"|");
1914  strcat(rpcaux,servp->serv_def);
1915  if(servp->serv_id & 0x10000000)
1916  strcat(rpcaux,"|CMD\n");
1917  else
1918  strcat(rpcaux,"|\n");
1919  strcpy(rpcptr, rpcaux);
1920  rpcptr += (int)strlen(rpcaux);
1921  }
1922  }
1923  *rpcptr = '\0';
1924  id[0] = dis_get_conn_id();
1925  id[1] = 0;
1927  free(Service_info_list);
1928 }
1929 
1930 void get_rpc_info(int *tag, char **buffer, int *size)
1931 {
1932 
1933  if(tag){}
1934  *buffer = Rpc_info;
1935  *size = (int)strlen(Rpc_info)+1;
1936 }
1937 
#define STA_DATA
Definition: dim.h:198
char node_name[MAX_NODE_NAME]
Definition: dim.h:431
void update_did()
Definition: dns.c:573
struct node * client_next
Definition: dns.c:27
#define MAX_REGISTRATION_UNIT
Definition: dim.h:161
#define MAX_NAME
Definition: dim.h:182
static int wake_up
Definition: dns.c:81
Definition: dns.c:26
void kill_servers(int *tag, int *code, int *size)
Definition: dns.c:1568
static void release_conn(int conn_id)
Definition: dns.c:1077
int protocol
Definition: dim.h:438
int dim_get_keepalive_timeout()
Definition: tcpip.c:128
void do_inform_clients(int conn_id)
Definition: dns.c:942
void dna_test_write(int conn_id)
Definition: dna.c:335
void inform_clients(DNS_SERVICE *servp)
Definition: dns.c:984
DllExp DIM_NOSHARE int Curr_N_Conns
Definition: conn_handler.c:33
int handle_registration(int conn_id, DIS_DNS_PACKET *packet, int tmout_flag)
Definition: dns.c:176
int dna_write(int conn_id, void *buffer, int size)
Definition: dna.c:455
#define dis_selective_update_service
Definition: dis.h:24
struct serv DNS_SERVICE
char node_addr[4]
Definition: dim.h:433
int dim_wait(void)
Definition: dim_thr.c:409
TIMR_ENT * timr_ent
Definition: dim.h:442
static int Rpc_id
Definition: dns.c:81
struct red_node * prev
Definition: dns.c:38
SERVICE_REQ service
Definition: dim.h:302
char task[MAX_TASK_NAME]
Definition: dim.h:408
DllExp DIM_NOSHARE DNS_CONNECTION * Dns_conns
Definition: conn_handler.c:29
#define STA_DISC
Definition: dim.h:197
static char DNS_accepted_domains[1024]
Definition: dns.c:88
int i
Definition: db_dim_client.c:21
DllExp DIM_NOSHARE NET_CONNECTION * Net_conns
Definition: conn_handler.c:32
Definition: dns.c:58
#define TRUE
Definition: dim.h:135
static int Server_info_id
Definition: dns.c:81
void * id_get_ptr(int id, SRC_TYPES type)
Definition: conn_handler.c:184
struct serv * servp
Definition: dns.c:41
void set_rpc_info(int *tag, char *buffer, int *size)
Definition: dns.c:1824
int serv_id
Definition: dns.c:66
void dll_insert_queue(DLL *head, DLL *item)
Definition: dll.c:23
char serv_name[MAX_NAME]
Definition: dns.c:49
#define DNS_TASK
Definition: dim.h:138
struct serv * servp
Definition: dns.c:33
char node[MAX_NODE_NAME]
Definition: dim.h:338
char * service_head
Definition: dim.h:436
static char DNS_accepted_nodes[1024]
Definition: dns.c:89
#define FALSE
Definition: dim.h:136
int dna_close(int conn_id)
Definition: dna.c:835
int dtq_create()
Definition: dtq.c:353
int type
Definition: dim.h:288
char node_addr[4]
Definition: dim.h:274
void print_stats()
Definition: dns.c:1499
void * malloc()
Definition: EventBuilder.cc:99
void dna_rem_test_write(int conn_id)
Definition: dna.c:613
FILE * foutptr
Definition: dns.c:24
void get_new_dns_server_info(int *tag, int **bufp, int *size, int *first_time)
Definition: dns.c:1296
char node_addr[4]
Definition: dim.h:312
char service_def[MAX_NAME]
Definition: dim.h:309
char id[4]
Definition: FITS.h:71
#define DNS_DIS_HEADER
Definition: dim.h:291
void do_update_did(int conn_id)
Definition: dns.c:587
char task_name[MAX_TASK_NAME-4]
Definition: dim.h:273
void dna_set_test_write(int conn_id, int time)
Definition: dna.c:606
void dll_init(DLL *head)
Definition: dll.c:14
void set_in_error(int conn_id)
Definition: dns.c:1199
char task[MAX_TASK_NAME]
Definition: dim.h:339
char node[MAX_NODE_NAME]
Definition: dim.h:407
_DIM_PROTO(DNS_SERVICE *service_exists,(char *name))
struct red_node * next
Definition: dns.c:37
int state
Definition: dns.c:63
int main(int argc, char **argv)
Definition: dns.c:1419
static char * Rpc_info
Definition: dns.c:85
int protocol
Definition: dim.h:277
struct red_serv * next
Definition: dns.c:59
int service_id
Definition: dim.h:265
char serv_def[MAX_NAME]
Definition: dns.c:62
int service_id
Definition: dns.c:32
int dis_get_conn_id()
Definition: dis.c:2795
char node_name[MAX_NODE_NAME]
Definition: dim.h:310
int conn_id
Definition: dns.c:31
char serv_name[MAX_NAME]
Definition: dns.c:61
char service_name[MAX_NAME]
Definition: dim.h:264
void dll_remove(DLL *item)
Definition: dll.c:100
int conn_id
Definition: dns.c:52
int n_services
Definition: dim.h:279
int protocol
Definition: dim.h:315
static int Curr_n_servers
Definition: dns.c:73
struct red_serv RED_DNS_SERVICE
void service_remove(RED_DNS_SERVICE *servp)
Definition: dns.c:1641
DNS_SERVER_INFO server
Definition: dim.h:345
void set_debug_on()
Definition: dns.c:1556
#define DNS_DIC_HEADER
Definition: dim.h:319
int format
Definition: dim.h:278
SRC_TYPES src_type
Definition: dim.h:301
char node_name[MAX_NODE_NAME]
Definition: dim.h:272
int format
Definition: dim.h:316
void conn_arr_create(SRC_TYPES type)
Definition: conn_handler.c:49
void print_hash_table()
Definition: dns.c:1667
void check_validity(int conn_id)
Definition: dns.c:610
char task_name[MAX_TASK_NAME-4]
Definition: dim.h:432
#define dis_add_cmnd
Definition: dis.h:13
void dim_set_listen_backlog(int size)
Definition: tcpip.c:113
int pid
Definition: dim.h:434
RED_NODE * node_head
Definition: dns.c:55
struct node * client_prev
Definition: dns.c:28
#define MAX_HASH_ENTRIES
Definition: dns.c:23
Definition: dim.h:530
void dtq_start_timer(int time, void(*user_routine)(), dim_long tag)
Definition: dtq.c:790
static int Last_conn_id
Definition: dns.c:74
void dim_init()
Definition: dim_thr.c:111
static int Rpc_info_size
Definition: dns.c:86
static void error_handler(int conn_id, int severity, int errcode, char *reason)
Definition: dns.c:162
static void recv_rout(int conn_id, DIC_DNS_PACKET *packet, int size, int status)
Definition: dns.c:105
int server_format
Definition: dns.c:65
Definition: dis.c:69
int type
int server_format
Definition: dns.c:53
int size
Definition: dim.h:287
int dtq_rem_entry(int queue_id, TIMR_ENT *entry)
Definition: dtq.c:503
struct serv * server_next
Definition: dns.c:45
#define dis_start_serving
Definition: dis.h:8
static char RPC_dummy
Definition: dns.c:84
#define dis_update_service
Definition: dis.h:18
char service_def[MAX_NAME]
Definition: dim.h:266
int find_services(char *wild_name)
Definition: dns.c:1718
char name[MAX_NAME]
Definition: dim.h:331
#define MAX_TASK_NAME
Definition: dim.h:181
void service_init()
Definition: dns.c:1620
int validity
Definition: dim.h:439
int get_dns_accepted_nodes(char *nodes)
Definition: utilities.c:275
void dim_set_write_timeout(int secs)
Definition: tcpip.c:141
int state
Definition: dns.c:51
void service_insert(RED_DNS_SERVICE *servp)
Definition: dns.c:1631
Warning because the service this data corrsponds to might have been last updated longer ago than Local time
Definition: smartfact.txt:92
int size
Definition: dim.h:300
struct serv * next
Definition: dis.c:70
struct serv * server_prev
Definition: dns.c:46
static int Server_new_info_id
Definition: dns.c:81
#define WATCHDOG_TMOUT_MAX
Definition: dim.h:175
char serv_def[MAX_NAME]
Definition: dns.c:50
DNS_SERVICE * service_exists(char *name)
Definition: dns.c:1649
int dna_write_nowait(int conn_id, void *buffer, int size)
Definition: dna.c:412
int handle_client_request(int conn_id, DIC_DNS_PACKET *packet)
Definition: dns.c:660
int n_services
Definition: dim.h:440
int buffer[BUFFSIZE]
Definition: db_dim_client.c:14
int dll_empty(DLL *head)
Definition: dll.c:88
int count
Definition: db_dim_server.c:18
int status
Definition: dim.h:333
int get_dns_port_number()
Definition: utilities.c:216
void dim_set_keepalive_timeout(int secs)
Definition: tcpip.c:123
int port
Definition: dim.h:435
int dna_open_server(char *task, void(*read_ast)(), int *protocol, int *port, void(*error_ast)())
Definition: dna.c:551
int size
Definition: db_dim_server.c:17
void id_free(int id, SRC_TYPES type)
Definition: conn_handler.c:206
struct node NODE
#define dis_send_service
Definition: dis.h:20
int port
Definition: dim.h:276
static int Timer_q
Definition: dns.c:80
void free(void *mem)
struct node * next
Definition: dns.c:29
TIMR_ENT * dtq_add_entry(int queue_id, int time, void(*user_routine)(), dim_long tag)
Definition: dtq.c:399
DllExp DIM_NOSHARE DNA_CONNECTION * Dna_conns
Definition: conn_handler.c:31
DLL * dll_get_next(DLL *head, DLL *item)
Definition: dll.c:66
#define MAX_NODE_NAME
Definition: dim.h:180
int dim_set_write_buffer_size(int size)
Definition: tcpip.c:160
#define dis_add_service
Definition: dis.h:12
void dim_print_date_time()
Definition: utilities.c:134
void dim_print_msg(char *msg, int severity)
Definition: utilities.c:180
Definition: dim.h:344
static int Debug
Definition: dns.c:78
int HashFunction(char *name, int max)
Definition: hash.c:22
#define DIM_VERSION_NUMBER
Definition: dim.h:16
int service_id
Definition: dns.c:40
SRC_TYPES src_type
Definition: dim.h:430
char * node_head
Definition: dim.h:437
int n_services
Definition: dim.h:341
static RED_DNS_SERVICE * Service_hash_table[MAX_HASH_ENTRIES]
Definition: dns.c:71
int service_id
Definition: dim.h:308
int pid
Definition: dim.h:275
int already
Definition: dim.h:443
SERVICE_REG services[MAX_SERVICE_UNIT]
Definition: dim.h:280
struct red_serv * prev
Definition: dns.c:60
RED_NODE * node_head
Definition: dns.c:67
char task_name[MAX_TASK_NAME-4]
Definition: dim.h:311
int get_node_name(char *node_name)
Definition: utilities.c:33
static DNS_SERVICE ** Service_info_list
Definition: dns.c:70
DNS_SERVICE_INFO services[1]
Definition: dim.h:346
static int Curr_n_services
Definition: dns.c:72
char long_task_name[MAX_NAME]
Definition: dim.h:444
#define MY_OS9
Definition: dim.h:26
int pid
Definition: dim.h:313
int conn_id
Definition: dns.c:39
sprintf(name1,"NewService%d", i)
void set_debug_off()
Definition: dns.c:1562
void get_rpc_info(int *tag, char **buffer, int *size)
Definition: dns.c:1930
int conn_id
Definition: dns.c:64
int old_n_services
Definition: dim.h:441
int serv_id
Definition: dns.c:54
#define STA_CONN
Definition: dim.h:199
struct red_node RED_NODE
int get_dns_accepted_domains(char *domains)
Definition: utilities.c:249
struct node * prev
Definition: dns.c:30
DLL * dll_search(DLL *head, char *data, int size)
Definition: dll.c:49
void get_dns_server_info(int *tag, int **bufp, int *size, int *first_time)
Definition: dns.c:1216
int dim_set_read_buffer_size(int size)
Definition: tcpip.c:176
int port
Definition: dim.h:314
void send_dns_server_info(int conn_id, int **bufp, int *size)
Definition: dns.c:1239
int conn_get()
Definition: conn_handler.c:79
int size
Definition: dim.h:307
Definition: dns.c:36