/* * A utility file. * * Started date : 10-11-91 * Written by : C. Gaspar * UNIX adjustment: G.C. Ballintijn * */ #define DIMLIB #include #define MAX_DNS_NODE 256 typedef struct { char node_name[MAX_NODE_NAME]; char task_name[MAX_TASK_NAME]; void (*recv_rout)(); void (*error_rout)(); TIMR_ENT *timr_ent; SRC_TYPES src_type; } PENDING_CONN; typedef struct dns_ent{ struct dns_ent *next; struct dns_ent *prev; char node_name[MAX_DNS_NODE]; char task_name[MAX_TASK_NAME]; int port_number; void (*recv_rout)(); void (*error_rout)(); TIMR_ENT *timr_ent; SRC_TYPES src_type; int conn_id; int pending; int connecting; } DNS_CONN; static int Timer_q = 0; static DNS_CONN *DNS_ids[3] = {0, 0, 0}; static DNS_CONN *DNS_conn_head = (DNS_CONN *)0; _DIM_PROTO( void retry_dns_connection, ( int conn_pend_id ) ); _DIM_PROTO( void init_dns_list, ( ) ); _DIM_PROTO( void set_dns_pars, ( DNS_CONN *connp, char *node, int port ) ); _DIM_PROTO( int get_dns_pars, ( DNS_CONN *connp, char *node, int *port ) ); int dim_set_dns_node(char *node) { init_dns_list(); set_dns_pars(DNS_ids[SRC_DIS], node, 0); set_dns_pars(DNS_ids[SRC_DIC], node, 0); return(1); } int dic_set_dns_node(char *node) { init_dns_list(); set_dns_pars(DNS_ids[SRC_DIC], node, 0); return(1); } int dis_set_dns_node(char *node) { init_dns_list(); set_dns_pars(DNS_ids[SRC_DIS], node, 0); return(1); } int dim_get_dns_node(char *node) { register int node_exists; int port; init_dns_list(); node_exists = get_dns_pars(DNS_ids[SRC_DIS], node, &port); return(node_exists); } int dic_get_dns_node(char *node) { register int node_exists; int port; init_dns_list(); node_exists = get_dns_pars(DNS_ids[SRC_DIC], node, &port); return(node_exists); } int dis_get_dns_node(char *node) { register int node_exists; int port; init_dns_list(); node_exists = get_dns_pars(DNS_ids[SRC_DIS], node, &port); return(node_exists); } int dim_set_dns_port(int port) { init_dns_list(); set_dns_pars(DNS_ids[SRC_DIS], 0, port); set_dns_pars(DNS_ids[SRC_DIC], 0, port); return(1); } int dic_set_dns_port(int port) { init_dns_list(); set_dns_pars(DNS_ids[SRC_DIC], 0, port); return(1); } int dis_set_dns_port(int port) { init_dns_list(); set_dns_pars(DNS_ids[SRC_DIS], 0, port); return(1); } int dim_get_dns_port() { int port; char node[MAX_DNS_NODE]; init_dns_list(); get_dns_pars(DNS_ids[SRC_DIS], node, &port); return(port); } int dic_get_dns_port() { int port; char node[MAX_DNS_NODE]; init_dns_list(); get_dns_pars(DNS_ids[SRC_DIC], node, &port); return(port); } int dis_get_dns_port() { int port; char node[MAX_DNS_NODE]; init_dns_list(); get_dns_pars(DNS_ids[SRC_DIS], node, &port); return(port); } int rand_tmout( int min, int max ) { int aux; aux = rand(); aux %= (max - min); aux += min; return(aux); } void init_dns_list() { char node[MAX_DNS_NODE]; int port; long sid, cid; DISABLE_AST if(!DNS_conn_head) { DNS_conn_head = (DNS_CONN *)malloc(sizeof(DNS_CONN)); dll_init( (DLL *) DNS_conn_head ); node[0] = '\0'; get_dns_node_name(node); port = get_dns_port_number(); sid = dis_add_dns(node, port); cid = dic_add_dns(node, port); DNS_ids[SRC_DIS] = (DNS_CONN *)sid; DNS_ids[SRC_DIC] = (DNS_CONN *)cid; } ENABLE_AST } void set_dns_pars(DNS_CONN *connp, char *node, int port) { if(node != 0) { strcpy(connp->node_name, node); } if(port != 0) { connp->port_number = port; } } int get_dns_pars(DNS_CONN *connp, char *node, int *port) { int exists = 0; if(connp->node_name[0]) { strcpy(node, connp->node_name); exists = 1; } *port = connp->port_number; return exists; } DNS_CONN *find_dns(char *node_name, int port_number, SRC_TYPES src_type) { DNS_CONN *connp; connp = DNS_conn_head; while( (connp = (DNS_CONN *)dll_get_next( (DLL *) DNS_conn_head, (DLL*) connp)) ) { if(connp->src_type == src_type) { if((!strcmp(connp->node_name, node_name)) && (connp->port_number == port_number)) return connp; } } return (DNS_CONN *)0; } long dis_add_dns(char *node_name, int port_number) { DNS_CONN *connp; init_dns_list(); if(!(connp = find_dns(node_name, port_number, SRC_DIS))) { connp = (DNS_CONN *)malloc(sizeof(DNS_CONN)); strcpy(connp->node_name, node_name); connp->port_number = DNS_PORT; if(port_number != 0) connp->port_number = port_number; connp->src_type = SRC_DIS; connp->pending = 0; connp->conn_id = 0; connp->connecting = 0; dll_insert_queue( (DLL *) DNS_conn_head, (DLL *) connp ); } return (long)connp; } long dic_add_dns(char *node_name, int port_number) { DNS_CONN *connp; init_dns_list(); if(!(connp = find_dns(node_name, port_number, SRC_DIC))) { connp = (DNS_CONN *)malloc(sizeof(DNS_CONN)); strcpy(connp->node_name, node_name); connp->port_number = DNS_PORT; if(port_number != 0) connp->port_number = port_number; connp->src_type = SRC_DIC; connp->pending = 0; connp->conn_id = 0; connp->connecting = 0; dll_insert_queue( (DLL *) DNS_conn_head, (DLL *) connp ); } return (long)connp; } DNS_CONN *get_dns(DNS_CONN *connp, SRC_TYPES src_type) { DNS_CONN *p = 0; init_dns_list(); if(connp) { if(connp->src_type == src_type) { p = connp; } } else { p = DNS_ids[src_type]; } return p; } int close_dns(long dnsid, SRC_TYPES src_type) { DNS_CONN *connp; connp = get_dns((DNS_CONN *)dnsid, src_type); if( !Timer_q ) Timer_q = dtq_create(); if( connp->pending ) { connp->pending = 0; dtq_rem_entry( Timer_q, connp->timr_ent ); } return 1; } int open_dns(long dnsid, void (*recv_rout)(), void (*error_rout)(), int tmout_min, int tmout_max, SRC_TYPES src_type ) { char nodes[MAX_DNS_NODE]; char node_info[MAX_NODE_NAME+4]; register char *dns_node, *ptr; register int conn_id; register int timeout, node_exists; int i, dns_port; int rand_tmout(); DNS_CONN *connp; conn_id = 0; if( !Timer_q ) Timer_q = dtq_create(); connp = get_dns((DNS_CONN *)dnsid, src_type); node_exists = get_dns_pars(connp, nodes, &dns_port); if( !(connp->pending) ) { if(!node_exists) { return(-2); } ptr = nodes; while(1) { dns_node = ptr; if( (ptr = (char *)strchr(ptr,',')) ) { *ptr = '\0'; ptr++; } strcpy(node_info,dns_node); for(i = 0; i < 4; i ++) node_info[strlen(node_info)+i+1] = (char)0xff; connp->conn_id = 0; connp->connecting = 1; conn_id = dna_open_client( node_info, DNS_TASK, dns_port, TCPIP, recv_rout, error_rout, src_type ); connp->connecting = 0; if(conn_id) break; if( !ptr ) break; } connp->conn_id = conn_id; if(!conn_id) { strncpy(connp->task_name, DNS_TASK, MAX_TASK_NAME); connp->recv_rout = recv_rout; connp->error_rout = error_rout; connp->pending = 1; timeout = rand_tmout( tmout_min, tmout_max ); connp->timr_ent = dtq_add_entry( Timer_q, timeout, retry_dns_connection, connp ); return( -1); } } else return(-1); return(conn_id); } void retry_dns_connection( DNS_CONN *connp ) { char nodes[MAX_DNS_NODE]; char node_info[MAX_NODE_NAME+4]; register char *dns_node, *ptr; register int conn_id, node_exists; static int retrying = 0; int i, dns_port; if( retrying ) return; retrying = 1; conn_id = 0; node_exists = get_dns_pars(connp, nodes, &dns_port); if(node_exists) { ptr = nodes; while(1) { dns_node = ptr; if( (ptr = (char *)strchr(ptr,',')) ) { *ptr = '\0'; ptr++; } strcpy(node_info,dns_node); for(i = 0; i < 4; i ++) node_info[strlen(node_info)+i+1] = (char)0xff; connp->conn_id = 0; connp->connecting = 1; conn_id = dna_open_client( node_info, connp->task_name, dns_port, TCPIP, connp->recv_rout, connp->error_rout, connp->src_type ); connp->connecting = 0; if( conn_id ) break; if( !ptr ) break; } } connp->conn_id = conn_id; if(conn_id) { connp->pending = 0; dtq_rem_entry( Timer_q, connp->timr_ent ); } retrying = 0; } long dns_get_dnsid(int conn_id, SRC_TYPES src_type) { DNS_CONN *connp; int found = 0; connp = DNS_conn_head; while( (connp = (DNS_CONN *)dll_get_next( (DLL *) DNS_conn_head, (DLL*) connp)) ) { if(connp->conn_id == conn_id) { found = 1; break; } else if((connp->conn_id == 0) && (connp->connecting)) { connp->conn_id = conn_id; found = 1; break; } } if(found) { if(connp == DNS_ids[src_type]) { return (long)0; } else { return (long)connp; } } return (long)-1; }