示例#1
0
static void datagram_close_async(struct mi_root *mi_rpl,struct mi_handler *hdl, int done)
{
    datagram_stream dtgram;
    int ret;
    my_socket_address *p;
    int reply_sock, flags;

    p = (my_socket_address *)hdl->param;

    LM_DBG("the socket domain is %i and af_local is %i\n", p->domain, AF_LOCAL);

    memset(&dtgram, 0, sizeof(dtgram));

    mi_create_dtgram_replysocket(reply_sock, p->domain, err);

    if (mi_rpl!=0) {
        /*allocate the response datagram*/
        dtgram.start = pkg_malloc(DATAGRAM_SOCK_BUF_SIZE);
        if(!dtgram.start) {
            LM_ERR("no more pkg memory\n");
            goto err;
        }
        /*build the response*/
        if(mi_datagram_write_tree(&dtgram , mi_rpl) != 0) {
            LM_ERR("failed to build the response \n");
            goto err;
        }
        LM_DBG("the response is %s", dtgram.start);

        /*send the response*/
        ret = mi_send_dgram(reply_sock, dtgram.start, dtgram.current - dtgram.start,
                            (struct sockaddr *)&p->address, p->address_len, mi_socket_timeout);
        if (ret>0) {
            LM_DBG("the response: %s has been sent in %i octets\n", dtgram.start, ret);
        } else {
            LM_ERR("failed to send the response, ret is %i\n",ret);
        }
        free_mi_tree(mi_rpl);
        pkg_free(dtgram.start);
        if (done) free_async_handler( hdl );
    } else if (done) {
        mi_send_dgram(reply_sock, MI_COMMAND_FAILED, MI_COMMAND_FAILED_LEN,
                      (struct sockaddr*)&reply_addr, reply_addr_len, mi_socket_timeout);
        free_async_handler( hdl );
    }

    close(reply_sock);
    return;

err:
    if(dtgram.start)
        pkg_free(dtgram.start);
    close(reply_sock);
    if (done) free_async_handler( hdl );
    return;
}
示例#2
0
static void datagram_close_async(struct mi_root *mi_rpl,struct mi_handler *hdl,
																	int done)
{
	datagram_stream dtgram;
	int ret;
	my_socket_address *p;

	p = (my_socket_address *)hdl->param;

	if ( mi_rpl!=0 || done )
	{
		if (mi_rpl!=0) {
			/*allocate the response datagram*/
			dtgram.start = pkg_malloc(DATAGRAM_SOCK_BUF_SIZE);
			if(!dtgram.start){
				LM_ERR("no more pkg memory\n");
				goto err;
			}
			/*build the response*/
			if(mi_datagram_write_tree(&dtgram , mi_rpl) != 0){
				LM_ERR("failed to build the response \n");
				goto err1;
			}
			LM_DBG("the response is %s", dtgram.start);

			/*send the response*/
			ret = mi_send_dgram(p->tx_sock, dtgram.start,
							dtgram.current - dtgram.start,
							 (struct sockaddr *)&p->address,
							 p->address_len, mi_socket_timeout);
			if (ret>0){
				LM_DBG("the response: %s has been sent in %i octets\n",
					dtgram.start, ret);
			}else{
				LM_ERR("failed to send the response, ret is %i\n",ret);
			}
			free_mi_tree( mi_rpl );
			pkg_free(dtgram.start);
		} else {
			mi_send_dgram(p->tx_sock, MI_COMMAND_FAILED, MI_COMMAND_FAILED_LEN,
							(struct sockaddr*)&reply_addr, reply_addr_len,
							mi_socket_timeout);
		}
	}

	if (done)
		free_async_handler( hdl );

	return;

err1:
	pkg_free(dtgram.start);
err:
	return;
}
示例#3
0
void mi_datagram_server(int rx_sock, int tx_sock)
{
	struct mi_root *mi_cmd;
	struct mi_root *mi_rpl;
	struct mi_handler *hdl;
	struct mi_cmd * f;
	datagram_stream dtgram;

	int ret, len;

	ret = 0;
	f = 0;

	while(1){/*read the datagram*/
		memset(mi_buf, 0, DATAGRAM_SOCK_BUF_SIZE);
		reply_addr_len = sizeof(reply_addr);

		/* get the client's address */
		ret = recvfrom(rx_sock, mi_buf, DATAGRAM_SOCK_BUF_SIZE, 0,
					(struct sockaddr*)&reply_addr, &reply_addr_len);

		if (ret == -1) {
			LM_ERR("recvfrom: (%d) %s\n", errno, strerror(errno));
			if ((errno == EINTR) ||
				(errno == EAGAIN) ||
				(errno == EWOULDBLOCK) ||
				(errno == ECONNREFUSED)) {
				LM_DBG("got %d (%s), going on\n", errno, strerror(errno));
				continue;
			}
			LM_DBG("error in recvfrom\n");
			continue;
		}

		if(ret == 0)
			continue;

		LM_DBG("received %.*s\n", ret, mi_buf);

		if(ret> DATAGRAM_SOCK_BUF_SIZE){
				LM_ERR("buffer overflow\n");
				continue;
		}

		LM_DBG("mi_buf is %s and we have received %i bytes\n",mi_buf, ret);
		dtgram.start 	= mi_buf;
		dtgram.len 		= ret;
		dtgram.current 	= dtgram.start;

		ret = identify_command(&dtgram, &f);
		/*analyze the command--from the first line*/
		if(ret != 0)
		{
			LM_ERR("command not available\n");
			mi_send_dgram(tx_sock, MI_COMMAND_NOT_AVAILABLE,
						  MI_COMMAND_AVAILABLE_LEN,
						  (struct sockaddr* )&reply_addr, reply_addr_len,
						  mi_socket_timeout);
			continue;
		}
		LM_DBG("we have a valid command \n");

		/* if asyncron cmd, build the async handler */
		if (f->flags&MI_ASYNC_RPL_FLAG) {
			hdl = build_async_handler(mi_socket_domain,
					&reply_addr, reply_addr_len, tx_sock);
			if (hdl==0) {
				LM_ERR("failed to build async handler\n");
				mi_send_dgram(tx_sock, MI_INTERNAL_ERROR,
						MI_INTERNAL_ERROR_LEN,(struct sockaddr* )&reply_addr,
						reply_addr_len, mi_socket_timeout);
				continue;
			}
		} else{
			hdl = 0;
		}

		LM_DBG("after identifing the command, the received datagram is  %s\n",
				dtgram.current);

		/*if no params required*/
		if (f->flags&MI_NO_INPUT_FLAG) {
			LM_DBG("the command has no params\n");
			mi_cmd = 0;
		} else {
			LM_DBG("parsing the command's params\n");
			mi_cmd = mi_datagram_parse_tree(&dtgram);
			if (mi_cmd==NULL){
				LM_ERR("failed to parse the MI tree\n");
				mi_send_dgram(tx_sock, MI_PARSE_ERROR, MI_PARSE_ERROR_LEN,
							  (struct sockaddr* )&reply_addr, reply_addr_len,
							  mi_socket_timeout);
				free_async_handler(hdl);
				continue;
			}
			mi_cmd->async_hdl = hdl;
		}

		LM_DBG("done parsing the mi tree\n");
		if ( (mi_rpl=run_mi_cmd(f, mi_cmd,
		(mi_flush_f *)mi_datagram_flush_tree, &dtgram))==0 ) {
		/*error while running the command*/
			LM_ERR("failed to process the command\n");
			mi_send_dgram(tx_sock, MI_COMMAND_FAILED, MI_COMMAND_FAILED_LEN,
							(struct sockaddr* )&reply_addr, reply_addr_len,
							mi_socket_timeout);
			goto failure;
		}

		/*the command exited well*/
		LM_DBG("command process (%s)succeded\n",f->name.s);

		if (mi_rpl!=MI_ROOT_ASYNC_RPL) {
			if(mi_datagram_write_tree(&dtgram , mi_rpl) != 0){
				LM_ERR("failed to build the response \n");
				goto failure;
			}

			len = dtgram.current - dtgram.start;
			ret = mi_send_dgram(tx_sock, dtgram.start,len,
							(struct sockaddr* )&reply_addr,
							reply_addr_len, mi_socket_timeout);
			if (ret>0){
				LM_DBG("the response: %s has been sent in %i octets\n",
					dtgram.start, ret);
			}else{
				LM_ERR("failed to send the response: %s (%d)\n",
					strerror(errno), errno);
			}
			free_mi_tree( mi_rpl );
			free_async_handler(hdl);
			if (mi_cmd) free_mi_tree( mi_cmd );
		}else {
			if (mi_cmd) free_mi_tree( mi_cmd );
		}

		continue;

failure:
		free_async_handler(hdl);
		/* destroy request tree */
		if (mi_cmd) free_mi_tree( mi_cmd );
		/* destroy the reply tree */
		if (mi_rpl) free_mi_tree(mi_rpl);
		continue;
	}
}