Example #1
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;
	}
}
void mi_fifo_server(FILE *fifo_stream)
{
    struct mi_root *mi_cmd;
    struct mi_root *mi_rpl;
    struct mi_handler *hdl;
    int line_len;
    char *file_sep, *command, *file;
    struct mi_cmd *f;
    FILE *reply_stream;

    while(1) {
        reply_stream = NULL;

        /* commands must look this way ':<command>:[filename]' */
        if (mi_read_line(mi_buf,MAX_MI_FIFO_BUFFER,fifo_stream, &line_len)) {
            LM_ERR("failed to read command\n");
            continue;
        }

        /* trim from right */
        while(line_len) {
            if(mi_buf[line_len-1]=='\n' || mi_buf[line_len-1]=='\r'
                    || mi_buf[line_len-1]==' ' || mi_buf[line_len-1]=='\t' ) {
                line_len--;
                mi_buf[line_len]=0;
            } else break;
        }

        if (line_len==0) {
            LM_DBG("command empty\n");
            continue;
        }
        if (line_len<3) {
            LM_ERR("command must have at least 3 chars\n");
            continue;
        }
        if (*mi_buf!=MI_CMD_SEPARATOR) {
            LM_ERR("command must begin with %c: %.*s\n", MI_CMD_SEPARATOR, line_len, mi_buf );
            goto consume1;
        }
        command = mi_buf+1;
        file_sep=strchr(command, MI_CMD_SEPARATOR );
        if (file_sep==NULL) {
            LM_ERR("file separator missing\n");
            goto consume1;
        }
        if (file_sep==command) {
            LM_ERR("empty command\n");
            goto consume1;
        }
        if (*(file_sep+1)==0) {
            file = NULL;
        } else {
            file = file_sep+1;
            file = get_reply_filename(file, mi_buf+line_len-file);
            if (file==NULL) {
                LM_ERR("trimming filename\n");
                goto consume1;
            }
        }
        /* make command zero-terminated */
        *file_sep=0;

        f=lookup_mi_cmd( command, strlen(command) );
        if (f==0) {
            LM_ERR("command %s is not available\n", command);
            mi_open_reply( file, reply_stream, consume1);
            mi_fifo_reply( reply_stream, "500 command '%s' not available\n",
                           command);
            goto consume2;
        }

        /* if asyncron cmd, build the async handler */
        if (f->flags&MI_ASYNC_RPL_FLAG) {
            hdl = build_async_handler( file, strlen(file) );
            if (hdl==0) {
                LM_ERR("failed to build async handler\n");
                mi_open_reply( file, reply_stream, consume1);
                mi_fifo_reply( reply_stream, "500 Internal server error\n");
                goto consume2;
            }
        } else {
            hdl = 0;
            mi_open_reply( file, reply_stream, consume1);
        }

        if (f->flags&MI_NO_INPUT_FLAG) {
            mi_cmd = 0;
            mi_do_consume();
        } else {
            mi_cmd = mi_parse_tree(fifo_stream);
            if (mi_cmd==NULL) {
                LM_ERR("error parsing MI tree\n");
                if (!reply_stream)
                    mi_open_reply( file, reply_stream, consume3);
                mi_fifo_reply( reply_stream, "400 parse error in "
                               "command '%s'\n", command);
                goto consume3;
            }
            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_flush_tree, reply_stream))==0 ) {
            if (!reply_stream)
                mi_open_reply( file, reply_stream, failure);
            mi_fifo_reply(reply_stream, "500 command '%s' failed\n", command);
            LM_ERR("command (%s) processing failed\n", command );
        } else if (mi_rpl!=MI_ROOT_ASYNC_RPL) {
            if (!reply_stream)
                mi_open_reply( file, reply_stream, failure);
            mi_write_tree( reply_stream, mi_rpl);
            free_mi_tree( mi_rpl );
        } else {
            if (mi_cmd) free_mi_tree( mi_cmd );
            continue;
        }

        free_async_handler(hdl);
        /* close reply fifo */
        fclose(reply_stream);
        /* destroy request tree */
        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;

consume3:
        free_async_handler(hdl);
        if (reply_stream)
consume2:
            fclose(reply_stream);
consume1:
        mi_do_consume();
    }
}
Example #3
0
xmlrpc_value*  default_method	(xmlrpc_env* 	env, 
								const char* 	host,
								const char* 	methodName,
								xmlrpc_value* 	paramArray,
								void* 			serverInfo)
#endif
{
	xmlrpc_value* ret = NULL;
	struct mi_root* mi_cmd = NULL;
	struct mi_root* mi_rpl = NULL;
	struct mi_handler *hdl = NULL;
	struct mi_cmd* f;
	char* response = 0;
	int is_shm = 0;

	LM_DBG("starting up.....\n");

	f = lookup_mi_cmd((char*)methodName, strlen(methodName));
	
	if ( f == 0 ) {
		LM_ERR("command %s is not available!\n", methodName);
		xmlrpc_env_set_fault_formatted(env, XMLRPC_NO_SUCH_METHOD_ERROR, 
			"Requested command (%s) is not available!", methodName);
		goto error;
	}

	LM_DBG("done looking the mi command.\n");

	/* if asyncron cmd, build the async handler */
	if (f->flags&MI_ASYNC_RPL_FLAG) {
		hdl = build_async_handler( );
		if (hdl==0) {
			LM_ERR("failed to build async handler\n");
			if ( !env->fault_occurred )
				xmlrpc_env_set_fault(env, XMLRPC_INTERNAL_ERROR,
					"Internal server error while processing request");
			goto error;
		}
	} else {
		hdl = NULL;
	}

	if (f->flags&MI_NO_INPUT_FLAG) {
		mi_cmd = 0;
	} else {
		mi_cmd = xr_parse_tree(env, paramArray);
		if ( mi_cmd == NULL ){
			LM_ERR("failed to parse MI tree\n");
			if ( !env->fault_occurred )
				xmlrpc_env_set_fault(env, XMLRPC_INTERNAL_ERROR,
					"The xmlrpc request could not be parsed into a MI tree!");
			goto error;
		}
		mi_cmd->async_hdl = hdl;
	}

	LM_DBG("done parsing the mi tree.\n");

	if ( ( mi_rpl = run_mi_cmd(f, mi_cmd) ) == 0 ){
		LM_ERR("command (%s) processing failed.\n", methodName);
		xmlrpc_env_set_fault_formatted(env, XMLRPC_INTERNAL_ERROR, 
			"Command (%s) processing failed.\n", methodName);
		goto error;
	} else if (mi_rpl==MI_ROOT_ASYNC_RPL) {
		mi_rpl = wait_async_reply(hdl);
		hdl = 0;
		if (mi_rpl==0) {
			xmlrpc_env_set_fault_formatted(env, XMLRPC_INTERNAL_ERROR, 
				"Command (%s) processing failed (async).\n", methodName);
			goto error;
		}
		is_shm = 1;
	}

	LM_DBG("done running the mi command.\n");

	if ( rpl_opt == 1 ) {
		if ( xr_build_response_array( env, mi_rpl ) != 0 ){
			if ( !env->fault_occurred ) {
				LM_ERR("failed parsing the xmlrpc response from the mi tree\n");
				xmlrpc_env_set_fault(env, XMLRPC_INTERNAL_ERROR, 
					"Failed to parse the xmlrpc response from the mi tree.");
				}
			goto error;
		}
		LM_DBG("done building response array.\n");

		ret = xr_response;
	} else {
		if ( (response = xr_build_response( env, mi_rpl )) == 0 ){
			if ( !env->fault_occurred ) {
				LM_ERR("failed parsing the xmlrpc response from the mi tree\n");
				xmlrpc_env_set_fault_formatted(env, XMLRPC_INTERNAL_ERROR,
					"Failed to parse the xmlrpc response from the mi tree.");
			}
			goto error;
		}
		LM_DBG("done building response.\n");

		ret = xmlrpc_build_value(env, "s", response);
	}

error:
	free_async_handler(hdl);
	if ( mi_cmd ) free_mi_tree( mi_cmd );
	if ( mi_rpl ) { is_shm?free_shm_mi_tree(mi_rpl):free_mi_tree(mi_rpl);}
	return ret;
}