source: trunk/FACT++/dim_v19r15/src/dns.c @ 10183

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