/*! ** @brief Lookup a DAG based using a host or service name. ** ** The name should be a string such as www_s.example.xia or host.example.xia. ** By convention services are indicated by '_s' appended to the service name. ** The memory returned is dynamically allocated and should be released with a ** call to free() when the caller is done with it. ** ** This is a very simple implementation of the name query function. ** It will be replaces in a future release. ** ** @param name The name of an XIA service or host. ** ** @returns a character point to the dag on success ** @returns NULL on failure ** */ int XgetDAGbyName(const char *name, sockaddr_x *addr, socklen_t *addrlen) { int sock; sockaddr_x ns_dag; char pkt[NS_MAX_PACKET_SIZE]; char *dag; char _name[NS_MAX_DAG_LENGTH], _dag[NS_MAX_DAG_LENGTH]; int result; if (!addr || !addrlen || *addrlen < sizeof(sockaddr_x)) { errno = EINVAL; return -1; } // see if name is registered in the local hosts.xia file if((dag = hostsLookup(name))) { Graph g(dag); free(dag); // check to see if the returned dag was valid // we may want a better check for this in the future if (g.num_nodes() > 0) { std::string s = g.dag_string(); g.fill_sockaddr((sockaddr_x*)addr); *addrlen = sizeof(sockaddr_x); return 0; } } // not found locally, check the name server if ((sock = Xsocket(AF_XIA, SOCK_DGRAM, 0)) < 0) return -1; //Read the nameserver DAG (the one that the name-query will be sent to) if ( XreadNameServerDAG(sock, &ns_dag) < 0 ) { LOG("Unable to find nameserver address"); errno = NO_RECOVERY; return -1; } //Construct a name-query packet ns_pkt query_pkt; query_pkt.type = NS_TYPE_QUERY; query_pkt.name = strdup(name); memset(pkt, 0, sizeof(pkt)); int offset = 0; memcpy(pkt, &query_pkt.type, sizeof(query_pkt.type)); offset += sizeof(query_pkt.type); memcpy(pkt+offset, query_pkt.name, strlen(query_pkt.name)+1); offset += strlen(query_pkt.name)+1; //Send a name query to the name server Xsendto(sock, pkt, offset, 0, (const struct sockaddr*)&ns_dag, sizeof(sockaddr_x)); //Check the response from the name server memset(pkt, 0, sizeof(pkt)); int rc = Xrecvfrom(sock, pkt, NS_MAX_PACKET_SIZE, 0, NULL, NULL); if (rc < 0) { perror("recvfrom"); } memset(_name, '\0', NS_MAX_DAG_LENGTH); memset(_dag, '\0', NS_MAX_DAG_LENGTH); ns_pkt *tmp = (ns_pkt *)pkt; char* tmp_name = (char*)(pkt+sizeof(tmp->type)); char* tmp_dag = (char*)(pkt+sizeof(tmp->type)+ strlen(tmp_name)+1); switch (tmp->type) { case NS_TYPE_RESPONSE: sprintf(_name, "%s", tmp_name); sprintf(_dag, "%s", tmp_dag); result = 1; break; case NS_TYPE_RESPONSE_ERROR: result = -1; break; default: LOG("Unknown nameserver response"); result = -1; break; } Xclose(sock); free(query_pkt.name); if (result < 0) { return result; } Graph g(_dag); g.fill_sockaddr(addr); return 0; }
/*! ** @brief Register a service or hostname with the name server. ** ** Register a host or service name with the XIA nameserver. ** By convention services are indicated by '_s' appended to the service name. ** The memory returned is dynamically allocated and should be released with a ** call to free() when the caller is done with it. ** ** This is a very simple implementation and will be replaced in a ** future release. This version does not check correctness of the name or dag, ** nor does it check to ensure that the client is allowed to bind to name. ** ** @param name - The name of an XIA service or host. ** @param DAG - the DAG to be bound to name. ** ** @returns 0 on success ** @returns -1 on failure with errno set ** */ int XregisterName(const char *name, sockaddr_x *DAG) { int sock; sockaddr_x ns_dag; char pkt[NS_MAX_PACKET_SIZE]; char _name[NS_MAX_DAG_LENGTH], _dag[NS_MAX_DAG_LENGTH]; int result; if ((sock = Xsocket(AF_XIA, SOCK_DGRAM, 0)) < 0) return -1; //Read the nameserver DAG (the one that the name-registration will be sent to) if (XreadNameServerDAG(sock, &ns_dag) < 0) { LOG("Unable to find nameserver address"); errno = NO_RECOVERY; return -1; } if (!DAG) { errno = EINVAL; return -1; } Graph g(DAG); if (g.num_nodes() <= 0) { errno = EINVAL; return -1; } //Construct a registration packet ns_pkt register_pkt; register_pkt.type = NS_TYPE_REGISTER; register_pkt.name = strdup(name); register_pkt.dag = strdup(g.dag_string().c_str()); memset(pkt, 0, sizeof(pkt)); int offset = 0; memcpy(pkt, ®ister_pkt.type, sizeof(register_pkt.type)); offset += sizeof(register_pkt.type); memcpy(pkt+offset, register_pkt.name, strlen(register_pkt.name)+1); offset += strlen(register_pkt.name)+1; memcpy(pkt+offset, register_pkt.dag, strlen(register_pkt.dag)+1); offset += strlen(register_pkt.dag)+1; //Send the name registration packet to the name server //FIXME: use sockaddr here Xsendto(sock, pkt, offset, 0, (const struct sockaddr *)&ns_dag, sizeof(sockaddr_x)); //Check the response from the name server memset(pkt, 0, sizeof(pkt)); int rc = Xrecvfrom(sock, pkt, NS_MAX_PACKET_SIZE, 0, NULL, NULL); if (rc < 0) { perror("recvfrom"); } memset(_name, '\0', NS_MAX_DAG_LENGTH); memset(_dag, '\0', NS_MAX_DAG_LENGTH); ns_pkt *tmp = (ns_pkt *)pkt; char* tmp_name = (char*)(pkt+sizeof(tmp->type)); char* tmp_dag = (char*)(pkt+sizeof(tmp->type)+ strlen(tmp_name)+1); switch (tmp->type) { case NS_TYPE_RESPONSE: sprintf(_name, "%s", tmp_name); sprintf(_dag, "%s", tmp_dag); result = 0; break; case NS_TYPE_RESPONSE_ERROR: result = -1; break; default: fprintf(stderr, "dafault\n"); result = -1; break; } free(register_pkt.name); free(register_pkt.dag); Xclose(sock); return result; }
/*! ** @brief Lookup a DAG based using a host or service name. ** ** The name should be a string such as www_s.example.xia or host.example.xia. ** By convention services are indicated by '_s' appended to the service name. ** The memory returned is dynamically allocated and should be released with a ** call to free() when the caller is done with it. ** ** This is a very simple implementation of the name query function. ** It will be replaces in a future release. ** ** @param name The name of an XIA service or host. ** ** @returns a character point to the dag on success ** @returns NULL on failure ** */ char *XgetDAGbyName(const char *name) { int sock; char pkt[NS_MAX_PACKET_SIZE],ddag[NS_MAX_PACKET_SIZE], ns_dag[NS_MAX_PACKET_SIZE]; char *dag; char _name[NS_MAX_DAG_LENGTH], _dag[NS_MAX_DAG_LENGTH]; int result; //Open socket sock=Xsocket(XSOCK_DGRAM); //Read the nameserver DAG (the one that the name-query will be sent to) if ( XreadNameServerDAG(sock, ns_dag) < 0 ) error("Reading nameserver address"); //Construct a name-query packet ns_pkt query_pkt; query_pkt.type = NS_TYPE_QUERY; query_pkt.name = (char*)malloc(strlen(name)+1); sprintf(query_pkt.name, "%s", name); //query_pkt.dag = (char*)malloc(strlen(DAG)+1); //sprintf(query_pkt.dag, "%s", DAG); memset(pkt, 0, sizeof(pkt)); int offset = 0; memcpy(pkt, &query_pkt.type, sizeof(query_pkt.type)); offset += sizeof(query_pkt.type); memcpy(pkt+offset, query_pkt.name, strlen(query_pkt.name)+1); offset += strlen(query_pkt.name)+1; //memcpy(pkt+offset, query_pkt.dag, strlen(query_pkt.dag)+1); //offset += strlen(query_pkt.dag)+1; //Send a name query to the name server Xsendto(sock, pkt, offset, 0, ns_dag, strlen(ns_dag)+1); //Check the response from the name server memset(pkt, 0, sizeof(pkt)); memset(ddag, 0, sizeof(ddag)); size_t ddaglen = sizeof(ddag); int rc = Xrecvfrom(sock, pkt, NS_MAX_PACKET_SIZE, 0, ddag, &ddaglen); if (rc < 0) { error("recvfrom"); } memset(_name, '\0', NS_MAX_DAG_LENGTH); memset(_dag, '\0', NS_MAX_DAG_LENGTH); ns_pkt *tmp = (ns_pkt *)pkt; char* tmp_name = (char*)(pkt+sizeof(tmp->type)); char* tmp_dag = (char*)(pkt+sizeof(tmp->type)+ strlen(tmp_name)+1); switch (tmp->type) { case NS_TYPE_RESPONSE: sprintf(_name, "%s", tmp_name); sprintf(_dag, "%s", tmp_dag); result = 1; break; case NS_TYPE_RESPONSE_ERROR: result = -1; break; default: fprintf(stderr, "dafault\n"); result = -1; break; } if (result < 0) { return NULL; } dag = (char*)malloc(sizeof(_dag) + 1); strcpy(dag, _dag); //Close socket Xclose(sock); free(query_pkt.name); return dag; }