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

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