Exemple #1
0
void echo_dgram()
{
	int sock;
	char buf[XIA_MAXBUF];
	sockaddr_x cdag;
	socklen_t dlen;
	int n;

	say("Datagram service started\n");

	if ((sock = Xsocket(AF_XIA, SOCK_DGRAM, 0)) < 0)
		die(-2, "unable to create the datagram socket\n");

	struct addrinfo *ai;
	if (Xgetaddrinfo(NULL, SID_DGRAM, NULL, &ai) != 0)
		die(-1, "getaddrinfo failure!\n");

	sockaddr_x *sa = (sockaddr_x*)ai->ai_addr;

	Graph g((sockaddr_x*)ai->ai_addr);
	printf("\nDatagram DAG\n%s\n", g.dag_string().c_str());

    if (XregisterName(DGRAM_NAME, sa) < 0 )
    	die(-1, "error registering name: %s\n", DGRAM_NAME);
	say("registered name: \n%s\n", DGRAM_NAME);

	if (Xbind(sock, (sockaddr *)sa, sizeof(sa)) < 0) {
		die(-3, "unable to bind to the dag\n");
	}

	pid_t pid = 0;

	// only need to fork if doing stream echo at the same time
	if (stream == 1)
		pid = fork();

	if (pid == 0) {
		while (1) {
			say("Dgram Server waiting\n");

			dlen = sizeof(cdag);
			memset(buf, 0, sizeof(buf));
			if ((n = Xrecvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *)&cdag, &dlen)) < 0) {
				warn("Recv error on socket %d, closing connection\n", pid);
				break;
			}

			say("dgram received %d bytes\n", n);

			if ((n = Xsendto(sock, buf, n, 0, (struct sockaddr *)&cdag, dlen)) < 0) {
				warn("%5d send error\n", pid);
				break;
			}

			say("dgram sent %d bytes\n", n);
		}

		Xclose(sock);
	}
}
/*
** do one send/receive operation on the specified socket
*/
int process(int sock)
{
	int size;
	int sent, received;
	char tdag[1024];
	size_t dlen;
	char buf1[XIA_MAXBUF], buf2[XIA_MAXBUF];

	if (pktSize == 0)
		size = (rand() % XIA_MAXBUF) + 1;
	else
		size = pktSize;
	randomString(buf1, size);

	if ((sent = Xsendto(sock, buf1, size, 0, sdag, strlen(sdag)+1)) < 0) {
		die(-4, "Send error %d on socket %d\n", errno, sock);
	}

	say("Xsock %4d sent %d bytes\n", sock, sent);

	memset(buf2, sizeof(buf2), 0);
	dlen = sizeof(tdag);
	if ((received = Xrecvfrom(sock, buf2, sizeof(buf2), 0, tdag, &dlen)) < 0)
		die(-5, "Receive error %d on socket %d\n", errno, sock);

	say("Xsock %4d received %d bytes\n", sock, received);

	if (sent != received || strcmp(buf1, buf2) != 0) {
		warn("Xsock %4d received data different from sent data! (bytes sent/recv'd: %d/%d)\n", 
				sock, sent, received);
	}

	return 0;
}
int main(int argc, char *argv[])
{
    int sock, n, chunkSock, acceptSock;
    size_t dlen;
    char buf[1024],theirDAG[1024];
    //char* reply="Got your message";
    char reply[1024];
    pid_t pid;
    char myAD[1024]; 
    char myHID[1024];    

    //Open socket
    sock=Xsocket(XSOCK_DGRAM);
    if (sock < 0) error("Opening socket");

    // read the localhost AD and HID
    if ( XreadLocalHostAddr(sock, myAD, sizeof(myAD), myHID, sizeof(myHID)) < 0 )
    	error("Reading localhost address");

    // make the src DAG (the one the server listens on)
    char * dag = (char*) malloc(snprintf(NULL, 0, "RE %s %s %s", myAD, myHID, SID0) + 1);
    sprintf(dag, "RE %s %s %s", myAD, myHID, SID0);  

    //Register this service name to the name server
    char * sname = (char*) malloc(snprintf(NULL, 0, "%s", SNAME) + 1);
    sprintf(sname, "%s", SNAME);      
    if (XregisterName(sname, dag) < 0 )
    	error("name register");

    //Bind to the DAG
    Xbind(sock,dag);

    while (1) {
    			//Receive packet
    			memset(&buf[0], 0, sizeof(buf));
			dlen = sizeof(theirDAG);
			n = Xrecvfrom(sock,buf,1024,0,theirDAG,&dlen);
			
			//n = Xrecv(acceptSock,buf,1024,0);
			
			if (n < 0) 
			    error("recvfrom");
			//printf("\nReceived a datagram from:%s len %d strlen %d\n",theirDAG, (int)dlen, (int)strlen(theirDAG));
			write(1,buf,n);
			
			memset(&reply[0], 0, sizeof(reply));
			strcat (reply, "Got your message: ");
			strcat (reply, buf);			

			//Reply to client
			Xsendto(sock,reply,strlen(reply)+1,0,theirDAG,strlen(theirDAG));
	
			//Xsend(acceptSock,reply,strlen(reply),0);
   

    }
    return 0;
}
int main(int argc, char *argv[])
{
    int sock, n;
    size_t dlen;
    char reply[128];
    char buffer[2048],theirDAG[1024];    

    //Open socket
    sock=Xsocket(XSOCK_DGRAM);
    if (sock < 0) 
	error("Opening socket");
	
    //Name query to the name server
    char * sname = (char*) malloc(snprintf(NULL, 0, "%s", SNAME) + 1);
    sprintf(sname, "%s", SNAME);      
    char * dag = XgetDAGbyName(sname);

    while(1)
    {
	printf("\nPlease enter the message (0 to exit): ");
	bzero(buffer,2048);
	fgets(buffer,2048,stdin);
	if (buffer[0]=='0'&&strlen(buffer)==2)
	    break;
	    
	//Use Xconnect() with Xsend()
	//Xsend(sock,buffer,strlen(buffer),0);
	
	//Or use Xsendto()

	Xsendto(sock,buffer,strlen(buffer),0,dag,strlen(dag)+1);
	printf("Sent\n");


	//Process reply from server
	dlen =  sizeof(theirDAG);
	n = Xrecvfrom(sock,reply,128,0,theirDAG,&dlen);
	//n = Xrecv(sock,reply,128,0);
	if (n < 0) 
	    error("recvfrom");
	//printf("Received a datagram from:%s\n",theirDAG);
	write(1,reply,n);
	printf("\n");
    }

    Xclose(sock);
    return 0;
}
/*
** do one send/receive operation on the specified socket
*/
int process(int sock)
{
        int size;
        int sent, received, rc;
        char buf1[XIA_MAXBUF], buf2[XIA_MAXBUF];

        if (pktSize == 0)
                size = (rand() % XIA_MAXBUF) + 1;
        else
                size = pktSize;
        randomString(buf1, size);

        if ((sent = Xsendto(sock, buf1, size, 0, (sockaddr*)sa, sizeof(sockaddr_x))) < 0) {
                die(-4, "Send error %d on socket %d\n", errno, sock);
        }

        say("Xsock %4d sent %d bytes\n", sock, sent);

        struct pollfd pfds[2];
        pfds[0].fd = sock;
        pfds[0].events = POLLIN;
        if ((rc = Xpoll(pfds, 1, 5000)) <= 0) {
                die(-5, "Poll returned %d\n", rc);
        }

        memset(buf2, 0, sizeof(buf2));
        if ((received = Xrecvfrom(sock, buf2, sizeof(buf2), 0, NULL, NULL)) < 0)
                die(-5, "Receive error %d on socket %d\n", errno, sock);

        say("Xsock %4d received %d bytes\n", sock, received);

        if (sent != received || strcmp(buf1, buf2) != 0) {
                warn("Xsock %4d received data different from sent data! (bytes sent/recv'd: %d/%d)\n",
                                sock, sent, received);
        }

        return 0;
}
Exemple #6
0
static int udp_tl_keepalive(void)
{
	char buf[4] = "jaK";
	eXosip_reg_t *jr;

	if (eXosip.keep_alive <= 0) {
		return 0;
	}

	if (udp_socket <= 0)
		return OSIP_UNDEFINED_ERROR;

	for (jr = eXosip.j_reg; jr != NULL; jr = jr->next) {
		if (jr->len > 0) {
			if (Xsendto(udp_socket, (const void *) buf, 4, 0,
					   (struct sockaddr *) &(jr->addr), jr->len) > 0) {
				OSIP_TRACE(osip_trace
						   (__FILE__, __LINE__, OSIP_INFO1, NULL,
							"eXosip: Keep Alive sent on UDP!\n"));
			}
		}
	}
	return OSIP_SUCCESS;
}
/*!
** @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;
}
/*!
** @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;
}
Exemple #9
0
static int
udp_tl_send_message(osip_transaction_t * tr, osip_message_t * sip, char *host,
					int port, int out_socket)
{
	int len = 0;
	size_t length = 0;
	struct addrinfo *addrinfo;
/*	 struct __eXosip_sockaddr addr; */
	sockaddr_x addr;
	char *message = NULL;

	char ipbuf[sizeof(sockaddr_x)];
	int i;
	osip_naptr_t *naptr_record=NULL;

	if (udp_socket <= 0)
		return -1;

	if (host == NULL) {
		host = sip->req_uri->host;
		if (sip->req_uri->port != NULL)
			port = osip_atoi(sip->req_uri->port);
		else
			port = 5060;
	}

	eXtl_update_local_target(sip);

	i = -1;
#ifndef MINISIZE
	if (tr==NULL)
	{
		_eXosip_srv_lookup(sip, &naptr_record);

		if (naptr_record!=NULL) {
			eXosip_dnsutils_dns_process(naptr_record, 1);
			if (naptr_record->naptr_state==OSIP_NAPTR_STATE_NAPTRDONE
				||naptr_record->naptr_state==OSIP_NAPTR_STATE_SRVINPROGRESS)
				eXosip_dnsutils_dns_process(naptr_record, 1);
		}

		if (naptr_record!=NULL && naptr_record->naptr_state==OSIP_NAPTR_STATE_SRVDONE)
		{
			/* 4: check if we have the one we want... */
			if (naptr_record->sipudp_record.name[0] != '\0'
				&& naptr_record->sipudp_record.srventry[naptr_record->sipudp_record.index].srv[0] != '\0') {
					/* always choose the first here.
					if a network error occur, remove first entry and
					replace with next entries.
					*/
					osip_srv_entry_t *srv;
					int n = 0;
					for (srv = &naptr_record->sipudp_record.srventry[naptr_record->sipudp_record.index];
						n < 10 && naptr_record->sipudp_record.srventry[naptr_record->sipudp_record.index].srv[0];
						srv = &naptr_record->sipudp_record.srventry[naptr_record->sipudp_record.index]) {
							if (srv->ipaddress[0])
								i = eXosip_get_addrinfo(&addrinfo, srv->ipaddress, srv->port, IPPROTO_UDP);
							else
								i = eXosip_get_addrinfo(&addrinfo, srv->srv, srv->port, IPPROTO_UDP);
							if (i == 0) {
								host = srv->srv;
								port = srv->port;
								break;
							}

							i = eXosip_dnsutils_rotate_srv(&naptr_record->sipudp_record);
							if (i<=0)
							{
								return -1;
							}
							if (i>=n)
							{
								return -1;
							}
							i = -1;
							/* copy next element */
							n++;
					}
			}
		}

		if (naptr_record!=NULL && naptr_record->keep_in_cache==0)
			osip_free(naptr_record);
		naptr_record=NULL;
	}
	else
	{
		naptr_record = tr->naptr_record;
	}

	if (naptr_record!=NULL)
	{
		/* 1: make sure there is no pending DNS */
		eXosip_dnsutils_dns_process(naptr_record, 0);
		if (naptr_record->naptr_state==OSIP_NAPTR_STATE_NAPTRDONE
			||naptr_record->naptr_state==OSIP_NAPTR_STATE_SRVINPROGRESS)
			eXosip_dnsutils_dns_process(naptr_record, 0);

		if (naptr_record->naptr_state==OSIP_NAPTR_STATE_UNKNOWN)
		{
			/* fallback to DNS A */
			if (naptr_record->keep_in_cache==0)
				osip_free(naptr_record);
			naptr_record=NULL;
			if (tr!=NULL)
				tr->naptr_record=NULL;
			/* must never happen? */
		}
		else if (naptr_record->naptr_state==OSIP_NAPTR_STATE_INPROGRESS)
		{
			/* 2: keep waiting (naptr answer not received) */
			return OSIP_SUCCESS + 1;
		}
		else if (naptr_record->naptr_state==OSIP_NAPTR_STATE_NAPTRDONE)
		{
			/* 3: keep waiting (naptr answer received/no srv answer received) */
			return OSIP_SUCCESS + 1;
		}
		else if (naptr_record->naptr_state==OSIP_NAPTR_STATE_SRVINPROGRESS)
		{
			/* 3: keep waiting (naptr answer received/no srv answer received) */
			return OSIP_SUCCESS + 1;
		}
		else if (naptr_record->naptr_state==OSIP_NAPTR_STATE_SRVDONE)
		{
			/* 4: check if we have the one we want... */
			if (naptr_record->sipudp_record.name[0] != '\0'
				&& naptr_record->sipudp_record.srventry[naptr_record->sipudp_record.index].srv[0] != '\0') {
					/* always choose the first here.
					if a network error occur, remove first entry and
					replace with next entries.
					*/
					osip_srv_entry_t *srv;
					int n = 0;
					for (srv = &naptr_record->sipudp_record.srventry[naptr_record->sipudp_record.index];
						n < 10 && naptr_record->sipudp_record.srventry[naptr_record->sipudp_record.index].srv[0];
						srv = &naptr_record->sipudp_record.srventry[naptr_record->sipudp_record.index]) {
							if (srv->ipaddress[0])
								i = eXosip_get_addrinfo(&addrinfo, srv->ipaddress, srv->port, IPPROTO_UDP);
							else
								i = eXosip_get_addrinfo(&addrinfo, srv->srv, srv->port, IPPROTO_UDP);
							if (i == 0) {
								host = srv->srv;
								port = srv->port;
								break;
							}

							i = eXosip_dnsutils_rotate_srv(&naptr_record->sipudp_record);
							if (i<=0)
							{
								return -1;
							}
							if (i>=n)
							{
								return -1;
							}
							i = -1;
							/* copy next element */
							n++;
					}
			}
		}
		else if (naptr_record->naptr_state==OSIP_NAPTR_STATE_NOTSUPPORTED
			||naptr_record->naptr_state==OSIP_NAPTR_STATE_RETRYLATER)
		{
			/* 5: fallback to DNS A */
			if (naptr_record->keep_in_cache==0)
				osip_free(naptr_record);
			naptr_record=NULL;
			if (tr!=NULL)
				tr->naptr_record=NULL;
		}
	}
#endif

	/* if SRV was used, destination may be already found */
	if (i != 0) {
		i = eXosip_get_addrinfo(&addrinfo, host, port, IPPROTO_UDP);
	}

	if (i != 0) {
		return -1;
	}

	memcpy(&addr, addrinfo->ai_addr, addrinfo->ai_addrlen);
	len = addrinfo->ai_addrlen;

	eXosip_freeaddrinfo(addrinfo);

	/* remove preloaded route if there is no tag in the To header
	 */
	{
		osip_route_t *route = NULL;
		osip_generic_param_t *tag = NULL;
		osip_message_get_route(sip, 0, &route);

		osip_to_get_tag(sip->to, &tag);
		if (tag == NULL && route != NULL && route->url != NULL) {
			osip_list_remove(&sip->routes, 0);
		}
		i = osip_message_to_str(sip, &message, &length);
		if (tag == NULL && route != NULL && route->url != NULL) {
			osip_list_add(&sip->routes, route, 0);
		}
	}

	if (i != 0 || length <= 0) {
		osip_free(message);
		return -1;
	}
/*
	switch (((struct sockaddr *) &addr)->sa_family) {
	case AF_INET:
		inet_ntop(((struct sockaddr *) &addr)->sa_family,
				  &(((struct sockaddr_in *) &addr)->sin_addr), ipbuf,
				  sizeof(ipbuf));
		break;
	case AF_INET6:
		inet_ntop(((struct sockaddr *) &addr)->sa_family,
				  &(((struct sockaddr_in6 *) &addr)->sin6_addr), ipbuf,
				  sizeof(ipbuf));
		break;
	default:
		strncpy(ipbuf, "(unknown)", sizeof(ipbuf));
		break;
	}

	OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO1, NULL,
						  "Message sent: (to dest=%s:%i)\n%s\n",
						  ipbuf, port, message));
*/
/*	Graph g(&addr);
	char * dag_str = g.dag_string().c_str(); */
	memcpy(ipbuf, &addr, len);
	
	if (osip_strcasecmp(host, ipbuf)!=0 && MSG_IS_REQUEST(sip)) {
		if (MSG_IS_REGISTER(sip)) {
			
			struct eXosip_dns_cache entry;

			memset(&entry, 0, sizeof(struct eXosip_dns_cache));
			snprintf(entry.host, sizeof(entry.host), "%s", host);
			snprintf(entry.ip, sizeof(entry.ip), "%s", ipbuf);
			eXosip_set_option(EXOSIP_OPT_ADD_DNS_CACHE, (void *) &entry);
			
		}
	}

	if (tr != NULL) {
		if (tr->ict_context != NULL)
			osip_ict_set_destination(tr->ict_context, osip_strdup(ipbuf), port);
		if (tr->nict_context != NULL)
			osip_nict_set_destination(tr->nict_context, osip_strdup(ipbuf), port);
	}

	if (0 >
		Xsendto(udp_socket, (const void *) message, length, 0,
			   (struct sockaddr *) &addr, len))
	{
#ifndef MINISIZE
		if (naptr_record!=NULL)
		{
			/* rotate on failure! */
			if (eXosip_dnsutils_rotate_srv(&naptr_record->sipudp_record)>0)
			{
				osip_free(message);
				return OSIP_SUCCESS + 1;	/* retry for next retransmission! */
			}
		}
#endif
		/* SIP_NETWORK_ERROR; */
		osip_free(message);
		return -1;
	}
	
	if (eXosip.keep_alive > 0) {
		if (MSG_IS_REGISTER(sip)) {
			eXosip_reg_t *reg = NULL;

			if (_eXosip_reg_find(&reg, tr) == 0) {
				memcpy(&(reg->addr), &addr, len);
				reg->len = len;
			}
		}
	}

#ifndef MINISIZE
	if (naptr_record!=NULL)
	{
		if (tr!=NULL && MSG_IS_REGISTER(sip) && tr->last_response==NULL)
		{
			/* failover for outgoing transaction */
			time_t now;
			now = time(NULL);
			OSIP_TRACE(osip_trace
				(__FILE__, __LINE__, OSIP_INFO2, NULL,
				"not yet answered\n"));
			if (tr != NULL && now - tr->birth_time > 10 && now - tr->birth_time < 13)
			{
				/* avoid doing this twice... */
				if (eXosip_dnsutils_rotate_srv(&naptr_record->sipudp_record)>0)
				{
					OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO1, NULL,
						"Doing failover: %s:%i->%s:%i\n",
						host, port,
						naptr_record->sipudp_record.srventry[naptr_record->sipudp_record.index].srv,
						naptr_record->sipudp_record.srventry[naptr_record->sipudp_record.index].port));
					osip_free(message);
					return OSIP_SUCCESS + 1;	/* retry for next retransmission! */
				}
			}
		}
	}
#endif

	osip_free(message);
	return OSIP_SUCCESS;
}
Exemple #10
0
int main()
{
    int sock;
    socklen_t len;
    char buf[XIA_MAXBUF];
	sockaddr_x client;
	time_t now;
	struct tm *t;

    // create a datagram socket
    if ((sock = Xsocket(AF_XIA, SOCK_DGRAM, 0)) < 0) {
		printf("error: unable to create the listening socket.\n");
		exit(1);
	}

	struct addrinfo *ai;
	if (Xgetaddrinfo(NULL, SID0, NULL, &ai) != 0) {
    	printf("error: unable to create source dag.");
		exit(1);
	}

	sockaddr_x *sa = (sockaddr_x*)ai->ai_addr;

    //Register this service name to the name server
    if (XregisterName(SNAME, sa) < 0) {
    	printf("error: unable to register name/dag combo");
		exit(1);
	}

    // bind to the DAG
    if (Xbind(sock, (struct sockaddr*)sa, sizeof(sockaddr_x)) < 0) {
		Xclose(sock);
		printf("error: unable to bind to %s\n", SNAME);
		exit(1);
	}

    while (1) {
		len = sizeof(client);
		if (Xrecvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr*)&client, &len) < 0) {
			printf("error receiving client request\n");
			// assume it's ok, and just keep listening
			continue;
		}

		// we don't care what the client said, so we'll just ignore it

		now = time(NULL);
		t = gmtime(&now);
		strftime(buf, sizeof(buf), "%c %Z", t);
		
		Graph g(&client);
		printf("request from:\n%s\n", g.dag_string().c_str());
			
		//Reply to client
		if (Xsendto(sock, buf, strlen(buf) + 1, 0, (struct sockaddr*)&client, sizeof(client)) < 0)
			printf("error sending time to the client\n");
    }

	Xclose(sock);
    return 0;
}
Exemple #11
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;
}