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

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