Пример #1
0
/* Send a message through network. The caller must make sure that the message 
 * can be injected in the network, with a previous call to 'net_can_send'.
 * When the message reaches the head of the input buffer in 'dst_node', event
 * 'receive_event' will be scheduled, and object 'msg' will be accessible. The 
 * message needs to be removed by the caller with an additional call to
 * 'net_receive', which will invalidate and free the 'msg' object. */
struct net_msg_t *net_send_ev(struct net_t *net, struct net_node_t *src_node,
		struct net_node_t *dst_node, int size, int receive_event,
		void *receive_stack)
{
	struct net_stack_t *stack;
	struct net_msg_t *msg;

	/* Check nodes */
	if (src_node->kind != net_node_end || dst_node->kind != net_node_end)
		fatal("%s: not end nodes.\n%s", __FUNCTION__,
				net_err_end_nodes);

	/* Create message */
	msg = net_msg_create(net, src_node, dst_node, size);

	/* Insert message into hash table of in-flight messages */
	net_msg_table_insert(net, msg);

	/* Start event-driven simulation */
	stack = net_stack_create(net, ESIM_EV_NONE, NULL);
	stack->msg = msg;
	stack->ret_event = receive_event;
	stack->ret_stack = receive_stack;
	esim_execute_event(EV_NET_SEND, stack);

	/* Return created message */
	return msg;
}
Пример #2
0
int dispatcher_active_io (buffer_state_t * read_buffer_state, buffer_state_t * write_buffer_state, void ** state)
{
    dispatcher_state_t * dispatcher_state = *(dispatcher_state_t **)state;
    int rc               = 0;
    net_msg_t *          recv_msg = NULL;


    /* Dispatcher connection state initialization */
    if (dispatcher_state == NULL)
    {
        scar_log (1, "%s: Error: the dispatcher_state object was not yet created!\n", __func__);
        rc = NET_RC_DISCONNECT;
        goto finalize_message_handling;
    }

#ifdef DEBUG
    scar_log (3, "   << %s\n", read_buffer_state -> buffer);
#endif

    /* Handle PASS message */
    /* if ((rc = handle_ftp_PASS (ftp_state, read_buffer_state, write_buffer_state)) != NET_RC_UNHANDLED) */
        /* goto finalize_message_handling; */


    /* Push message to the inbox_q */
    if (read_buffer_state && (read_buffer_state -> num_bytes > 0))
    {
        recv_msg = net_msg_create (NULL, read_buffer_state -> num_bytes);
        if (!recv_msg)
        {
            scar_log (1, "%s: Error: Couldn't create a net_message object. Out of memory\n", __func__);
            rc = NET_RC_DISCONNECT;
            goto finalize_message_handling;
        }
        /* Returning 0 is ok, 1 is not ok */
        copy_buffer_to_buffer (read_buffer_state, recv_msg -> msg);
    }



finalize_message_handling:
#ifdef DEBUG
    scar_log (3, "   >> %s\n", write_buffer_state -> buffer);
#endif
    *state = (void *) dispatcher_state;
    return rc;
}
Пример #3
0
int handle_ftp_LIST (ftp_state_t * ftp_state, buffer_state_t * read_buffer_state, buffer_state_t * write_buffer_state)
{
    const char *        cmd_trigger     = "LIST";
    unsigned char *     bufp            = &(read_buffer_state -> buffer)[read_buffer_state -> bytes_commited];
    char *              output          = NULL;
    /* char *              listed_info     = NULL; */
    net_msg_t *         msg = NULL;

    if (strncasecmp ((char *) bufp, cmd_trigger, strlen (cmd_trigger)) != 0)
    {
        /* No match */
        return NET_RC_UNHANDLED;
    }
    else
    {
        /* Handle stat */
        if (!ftp_state)
        {
            write_buffer_state -> num_bytes = snprintf ((char *) write_buffer_state -> buffer, write_buffer_state -> buffer_size, "500 Unrecoverable error!\r\n");
        }

        /* listed_info = malloc (sizeof (unsigned char) * PATH_MAX); */

        /* Building a dynamic format string, based on the PATH_MAX information */
        if (strncmp ((char *) read_buffer_state -> buffer, cmd_trigger, strlen(cmd_trigger) != 0))
        {
            return NET_RC_UNHANDLED;
        }
        else
        {
            /* Fetch output based on path */
            if (ftp_state -> vfs_cwd == NULL)
                ftp_state -> vfs_cwd = ftp_state -> vfs_root;

            if ((output = VFS_list_by_full_path (ftp_state -> vfs_cwd)))
            {
                /* Open data port to send bytes */
                /* Start Data thread */
                msg = net_msg_create (ftp_state -> mailbox_handle, strlen (output));
                if (!msg)
                {
                    write_buffer_state -> num_bytes = snprintf ((char *) write_buffer_state -> buffer, 
                                                                write_buffer_state -> buffer_size, 
                                                                "550 Directory is empty.\r\n");
                }
                else
                {
                    /* Pushing message to the outbox */
                    net_msg_set_dst_id (msg, CAT_FTP_MOVERS);
                    net_msg_push_to_outbox (ftp_state -> mailbox_handle, msg);

                    /* HACK */
                    /* msg -> msg -> num_bytes = snprintf ((char *) msg -> msg -> buffer, msg -> msg -> buffer_size, "226 transfer finished.\r\n"); */
                }

                /* Must free output */
                free(output);

                write_buffer_state -> num_bytes = snprintf ((char *) write_buffer_state -> buffer, write_buffer_state -> buffer_size, "150 Opening ASCII mode data connection for /bin/ls\r\n");
                if (write_buffer_state -> num_bytes >= write_buffer_state -> buffer_size)
                {
                    /* Buffer overrun */
                    return NET_RC_DISCONNECT;
                }
                else
                {
                    return NET_RC_MUST_WRITE;
                }
            }
            else
            {
                write_buffer_state -> num_bytes = snprintf ((char *) write_buffer_state -> buffer, write_buffer_state -> buffer_size, "550 Directory is empty.\r\n");
            }
        }
        /* Move commited bytes to next command in the buffer (if there) */
        move_bytes_commited_to_next_command (read_buffer_state);

        if (write_buffer_state -> num_bytes >= write_buffer_state -> buffer_size)
        {
            /* Buffer overrun */
            return NET_RC_DISCONNECT;
        }
        else
        {
            return NET_RC_MUST_WRITE;
        }
    }
}
Пример #4
0
int handle_ftp_PORT (ftp_state_t * ftp_state, buffer_state_t * read_buffer_state, buffer_state_t * write_buffer_state)
{
    const char *      cmd_trigger       = "PORT";
    unsigned char *   short_host_port   = NULL;
    unsigned char *   bufp              = &(read_buffer_state -> buffer)[read_buffer_state -> bytes_commited];
    char *            host              = NULL;
    unsigned short    port              = 0;
    net_msg_t *       msg               = NULL;

    if (strncasecmp ((char *) bufp, cmd_trigger, strlen (cmd_trigger)) != 0)
    {
        /* No match */
        return NET_RC_UNHANDLED;
    }
    else
    {
        short_host_port = malloc (sizeof (char) * 256);
        if (sscanf ((char *) bufp,
                    "PORT %255s*s", 
                    short_host_port) <= 0)
        {
            /* No match */
            free(short_host_port);
            return NET_RC_UNHANDLED;
        }
        else
        {
            /* Move commited bytes to next command in the buffer (if there) */
            move_bytes_commited_to_next_command (read_buffer_state);

            PORT_to_host_port (short_host_port, &host, &port);
            if (host != NULL)
            {
                scar_log (5, "%s: Got PORT information: %s:%d\n", __func__, host, port);

                /* Make Outbox message for a Data-Mover or VFS query */
                msg = net_msg_create (ftp_state -> mailbox_handle, 100);
                if (!msg)
                {
                    write_buffer_state -> num_bytes = snprintf ((char *) write_buffer_state -> buffer, 
                                                                write_buffer_state -> buffer_size, 
                                                                "500 PORT Failed due to other stuff\r\n");
                }
                else
                {
                    /* Fire off a connection back to the Client on the given host and port info */
                    /* s = firstTCPSocketConnectingCorrectly (host, port); */

                    /* Write message to open a port to the client - Active FTP */
                    msg -> msg -> num_bytes = snprintf ((char *) msg -> msg -> buffer, 
                                                        msg -> msg -> buffer_size, 
                                                        "PORT %s:%d\r\n", 
                                                        host, 
                                                        port);
                    /* Set undefined category, as you don't know what command will follow */
                    net_msg_set_category_id (msg, CAT_UNDEFINED);
    
                    /* Directly respond to the client with an OK */
                    write_buffer_state -> num_bytes = snprintf ((char *) write_buffer_state -> buffer, 
                                                                write_buffer_state -> buffer_size, 
                                                                "200 PORT Command succesful\r\n");
                }
            }
            else
            {
                scar_log (2, "%s: Parse error in PORT information.\n", __func__);
                write_buffer_state -> num_bytes = snprintf ((char *) write_buffer_state -> buffer, write_buffer_state -> buffer_size, "501 Error in IP Address or Port number in PORT message\r\n");
            }

            /* parse_short_host_port (short_host_port, &ft); */

            if (write_buffer_state -> num_bytes >= write_buffer_state -> buffer_size)
            {
                /* Buffer overrun */
                free(short_host_port);
                return NET_RC_DISCONNECT;
            }
            else
            {
                free(short_host_port);
                return NET_RC_MUST_WRITE;
            }
        }
    }
}