/*!
** @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, &register_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;
}
Exemple #3
0
/*!
** @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;
}