示例#1
0
文件: openvpn.c 项目: OpenVPN/openvpn
/**
 * Main event loop for OpenVPN in client mode, where only one VPN tunnel
 * is active.
 * @ingroup eventloop
 *
 * @param c - The context structure of the single active VPN tunnel.
 */
static void
tunnel_point_to_point(struct context *c)
{
    context_clear_2(c);

    /* set point-to-point mode */
    c->mode = CM_P2P;

    /* initialize tunnel instance */
    init_instance_handle_signals(c, c->es, CC_HARD_USR1_TO_HUP);
    if (IS_SIG(c))
    {
        return;
    }

    /* main event loop */
    while (true)
    {
        perf_push(PERF_EVENT_LOOP);

        /* process timers, TLS, etc. */
        pre_select(c);
        P2P_CHECK_SIG();

        /* set up and do the I/O wait */
        io_wait(c, p2p_iow_flags(c));
        P2P_CHECK_SIG();

        /* timeout? */
        if (c->c2.event_set_status == ES_TIMEOUT)
        {
            perf_pop();
            continue;
        }

        /* process the I/O which triggered select */
        process_io(c);
        P2P_CHECK_SIG();

        perf_pop();
    }

    uninit_management_callback();

    /* tear down tunnel instance (unless --persist-tun) */
    close_instance(c);
}
int main(int argc, char *argv[])
{
	struct command_hdr hdr;
	int len, last_opt, i, add_dash_opt;
	int input_fds[MAX_FDS], output_fds[MAX_FDS];
	int input_fds_count, output_fds_count;
	char tempdir[50] = "/tmp/qubes-gpg-split.XXXXXX";
	char fifo_in[50], fifo_out[50];
	int devnull;
	int input_pipe, output_pipe;
	char *qrexec_client_path = QREXEC_CLIENT_PATH, *qcp;
	char *remote_domain;
	pid_t pid;

	remote_domain = getenv("QUBES_GPG_DOMAIN");
	if (!remote_domain) {
		fprintf(stderr,
			"ERROR: Destination domain not defined! Set it with QUBES_GPG_DOMAIN env variable.\n");
		exit(1);
	}
	add_dash_opt = 0;
	last_opt = parse_options(argc, argv, input_fds, &input_fds_count,
				 output_fds, &output_fds_count, 1);
	if (last_opt < argc) {
		// open the first non-option argument as stdin
		int input_file;

		if (strcmp(argv[last_opt], "-") != 0) {
			/* open only when not already pointing at stdin */
			input_file = open(argv[last_opt], O_RDONLY);
			if (input_file < 0) {
				perror("open");
				exit(1);
			}
			dup2(input_file, 0);
			close(input_file);
		}
		add_dash_opt = 1;
	}
	len = 0;
	memset(hdr.command, 0, sizeof hdr.command);
	for (i = 0; i < last_opt; i++) {
		if (len + strlen(argv[i]) < COMMAND_MAX_LEN) {
			strcpy(&hdr.command[len], argv[i]);
			len += strlen(argv[i]) + 1;
		} else {
			fprintf(stderr, "ERROR: Command line too long\n");
			exit(1);
		}
	}
	if (add_dash_opt) {
		if (len + 2 < COMMAND_MAX_LEN) {
			strcpy(&hdr.command[len], "-");
			len += 2;
		} else {
			fprintf(stderr, "ERROR: Command line too long\n");
			exit(1);
		}
	}

	hdr.len = len ? len - 1 : 0;

	atexit(unlink_temps);
#ifndef DEBUG
	// setup fifos and run qrexec client
	if ((client_tempdir = mkdtemp(tempdir)) == NULL) {
		perror("mkdtemp");
		exit(1);
	}
#else
	client_tempdir = tempdir;
	mkdir(tempdir, 0700);
#endif
	snprintf(fifo_in, sizeof fifo_in, "%s/input", client_tempdir);
	if (mkfifo(fifo_in, 0600) < 0) {
		perror("mkfifo");
		exit(1);
	}
	fifo_in_created = 1;
	snprintf(fifo_out, sizeof fifo_out, "%s/output", client_tempdir);
	if (mkfifo(fifo_out, 0600) < 0) {
		perror("mkfifo");
		exit(1);
	}
	fifo_out_created = 1;

	switch (pid = fork()) {
	case -1:
		perror("fork");
		exit(1);
	case 0:
		devnull = open("/dev/null", O_RDONLY);
		if (devnull < 0) {
			perror("open /dev/null");
			exit(1);
		}
		dup2(devnull, 0);
		close(devnull);
		devnull = open("/dev/null", O_WRONLY);
		if (devnull < 0) {
			perror("open /dev/null");
			exit(1);
		}
		dup2(devnull, 1);
		close(devnull);

		qcp = getenv("QREXEC_CLIENT_PATH");
		if (qcp)
			qrexec_client_path = qcp;
		execl(qrexec_client_path, "qrexec_client_vm",
		      remote_domain, "qubes.Gpg", PIPE_CAT_PATH, fifo_in,
		      fifo_out, (char *) NULL);
		perror("exec");
		exit(1);
	}
	// parent

#ifdef DEBUG
	fprintf(stderr, "in: %s out: %s\n", fifo_in, fifo_out);
#endif

	input_pipe = open(fifo_in, O_RDONLY);
	if (input_pipe < 0) {
		perror("open");
		exit(1);
	}
	output_pipe = open(fifo_out, O_WRONLY);
	if (output_pipe < 0) {
		perror("open");
		exit(1);
	}

	len = write(output_pipe, &hdr, sizeof(hdr));
	if (len != sizeof(hdr)) {
		perror("write header");
		exit(1);
	}
#ifdef DEBUG
	fprintf(stderr, "input[0]: %d, in count: %d\n", input_fds[0],
		input_fds_count);
	fprintf(stderr, "input_pipe: %d\n", input_pipe);
#endif
	return process_io(input_pipe, output_pipe, input_fds,
			  input_fds_count, output_fds, output_fds_count);
}
示例#3
0
int
Exec::exec()
{
  int stdin_fd[2];
  int stdout_fd[2];
  int stderr_fd[2];

  // FIXME: Bad, we potentially leak file descriptors
  if (pipe(stdout_fd) < 0 || pipe(stderr_fd) < 0 || pipe(stdin_fd) < 0)
    throw std::runtime_error("Exec:exec(): pipe failed");

  pid_t pid = fork();
  if (pid < 0)
  { // error
    int errnum = errno;

    // Cleanup
    close(stdout_fd[0]);
    close(stdout_fd[1]);
    close(stderr_fd[0]);
    close(stderr_fd[1]);
    close(stdin_fd[0]);
    close(stdin_fd[1]);

    std::ostringstream out;
    out << "Exec::exec(): fork failed: " << strerror(errno);
    throw std::runtime_error(out.str());
  }
  else if (pid == 0) 
  { // child
    close(stdin_fd[1]);
    close(stdout_fd[0]);
    close(stderr_fd[0]);

    dup2(stdin_fd[0], STDIN_FILENO);
    close(stdin_fd[0]);

    dup2(stdout_fd[1], STDOUT_FILENO);
    close(stdout_fd[1]);

    dup2(stderr_fd[1], STDERR_FILENO);
    close(stderr_fd[1]);

    // Create C-style array for arguments 
    std::unique_ptr<char*[]> c_arguments(new char*[m_arguments.size()+2]);
    c_arguments[0] = strdup(m_program.c_str());
    for(std::vector<std::string>::size_type i = 0; i < m_arguments.size(); ++i)
      c_arguments[i+1] = strdup(m_arguments[i].c_str());
    c_arguments[m_arguments.size()+1] = NULL;
      
    // Execute the program
    if (m_absolute_path)
    {
      execv(c_arguments[0], c_arguments.get());
    }
    else
    {
      execvp(c_arguments[0], c_arguments.get());
    }
      
    int error_code = errno;

    // FIXME: this ain't proper, need to exit(1) on failure and signal error to parent somehow

    // execvp() only returns on failure 
    std::cout << "Exec::exec(): " << m_program << ": " << strerror(error_code) << std::endl;
    _exit(EXIT_FAILURE);
  }
  else // if (pid > 0)
  { // parent
    close(stdin_fd[0]);
    close(stdout_fd[1]);
    close(stderr_fd[1]);

    try 
    {
      process_io(stdin_fd[1], stdout_fd[0], stderr_fd[0]);
    }
    catch(std::exception& err)
    {
      int child_status = 0;
      waitpid(pid, &child_status, 0);
      throw;
    }

    int child_status = 0;
    waitpid(pid, &child_status, 0);

    return WEXITSTATUS(child_status);
  }
}
示例#4
0
static void update(void *arg, long period)
{
    gpio_t *pgpio = (gpio_t*)arg;
    int		   i;
    static int io_period = 0;
    static int fb_delay[MAX_AXIS] = {0};
    static int pos_err_old[MAX_AXIS] = {0};

//    static int* pTmr = NULL;

//    if( !pTmr )
//        pTmr = mapIoRegister( TIMER_BASE, 0x44 );

    static int update = 0, update_cnt = 0;
 //   if(*(pTmr + TCNTO0) != 0 )
 //       printf("TCON=%x, TCFG0=%x, TCFG1=%x, CNTB=%d, CMPB=%d, TCNTO0=%d\n", *(pTmr + TCON ), *(pTmr + TCFG0 ), *(pTmr + TCFG1 ), *(pTmr + TCNTB0 ), *(pTmr + TCMPB0 ), *(pTmr + TCNTO0) );

    if(pgpio->pfiq->underrun)
    {
        fprintf(stderr, "FIFO underrun!!!\n");
        pgpio->pfiq->underrun = 0;
    }
    // Update IO states only after desired period and if FIFO is half-full
    if (++io_period > io_update_period )
    {
        process_io();
        io_period = 0;
    }
    // If FIFO has maimum size, pause motion controller execution

    if(pgpio->pfiq->mdata.buffsize < fifo_deep)
    {
        *(pgpio->traj_wait) = 1;
    } else
    {
        *(pgpio->traj_wait) = 0;
        return;
    }

    for(i=0; i < num_axis; i++)
    {
        if(axis_map[i] >= 0)
        {
            // Copy actual position to the feedback
          *(pgpio->fb_pos[axis_map[i]]) = *(pgpio->cmd_pos[axis_map[i]]);
            if ( step_pins[i] >0 && dir_pins[i] > 0 )
            {
                long long aux, aux2, dist;

                aux = (long long) (*(pgpio->cmd_pos[axis_map[i]])*1000000.0f);
                // Calculate distance to go at this iteration
                dist = (aux - cmd_pos_prev[i])*(long long)step_per_unit[i]/10000LL;
                // Calculate absolut position from program start
                cmd_pos_accum[i] +=  dist;
                // Set desired position for FIQ stepgen
                pgpio->pfiq->mdata.buffer[pgpio->pfiq->mdata.PutPtr][i].cmd_position = cmd_pos_accum[i]/10000LL;

                //Check if last calculated correction of the position is already appliyed
                if(fb_delay[i] <= 0)
                {
                    // Due to FIQ jitter (cache miss, seems), we need correct position of the stepgen.
                    // Position error is calculated in the FIQ as following: pos_error = cmd_position - step_cnt
                    // Correction applyed by one step per the FIFO cycle
                    // Create dead band if error in range -1..1 to avoid rotor oscilation
                    // Check if already added correction is applied
                        int errDelta = pgpio->pfiq->pos_error[i] - pos_err_old[i];
                    if(errDelta != 0)
                    {
                        if(pgpio->pfiq->pos_error[i] < -1)
                        {
                            dist -= 100LL;
                        }
                        if(pgpio->pfiq->pos_error[i] > 1)
                        {
                            dist += 100LL;
                        }
                        pos_err_old[i] = pgpio->pfiq->pos_error[i];
                    }
                    fb_delay[i] = pgpio->pfiq->mdata.buffsize;
                } else fb_delay[i]--;
                // Calculate DSS adder value
                aux2 = dist * (1LL<<31)/1000000LL;
                // Strore adder and direction values in the FIFO
                if(aux2 > 0)
                {
                    pgpio->pfiq->mdata.buffer[pgpio->pfiq->mdata.PutPtr][i].adder = aux2;
                    pgpio->pfiq->mdata.buffer[pgpio->pfiq->mdata.PutPtr][i].direction = 0;
                } else
                {
                    pgpio->pfiq->mdata.buffer[pgpio->pfiq->mdata.PutPtr][i].adder = - aux2;
                    pgpio->pfiq->mdata.buffer[pgpio->pfiq->mdata.PutPtr][i].direction = 1;
                }
                if( scaner_compat !=0 && i == 0 )
                {
                    if(*(pgpio->scan_sync) != 0)
                        pgpio->pfiq->mdata.buffer[pgpio->pfiq->mdata.PutPtr][i].scan_sync = 1;
                    else
                        pgpio->pfiq->mdata.buffer[pgpio->pfiq->mdata.PutPtr][i].scan_sync = 0;
                }
                // Store last postion
                cmd_pos_prev[i] = aux;
            }
        }
#if 0
        if(update /* && (abs(pgpio->pfiq->pos_error[i]) > 10 )*/ )
        {
                fprintf(stderr, "putPtr=%d, buffsize=%d, step_cnt[%d]=%lld, pos_err[%d]=%lld\n"
                        , pgpio->pfiq->mdata.PutPtr
                        , pgpio->pfiq->mdata.buffsize
                        //, i
                        //, pgpio->pfiq->mdata.buffer[pgpio->pfiq->mdata.PutPtr][i].cmd_position
                        , i
                        , pgpio->pfiq->step_count[i], i, pgpio->pfiq->pos_error[i] );
        }
#endif
    }
#if 0
        update = 0;
        if(++update_cnt >= 500)
        {
 //           printf("scan_sync=%d\n", *(pgpio->scan_sync) );
            update_cnt = 0;
            update = 1;
        };
#endif
    // To avoid simultaneous access to the buffsize, we increment it in the FIQ handler
    pgpio->pfiq->mdata.ringbuff_update = 1;

    // Increment put position
    if(++pgpio->pfiq->mdata.PutPtr  >= fifo_deep)
    {
        pgpio->pfiq->mdata.PutPtr = 0;
    }
}
示例#5
0
NETLIB_API void idle_slave(bool _can_block)
{
    process_io(_can_block);
}
示例#6
0
NETLIB_API void idle(bool _can_block)
{
    process_io(_can_block);
    thread::sleep(0);
}
示例#7
0
void backend()
{
    struct timeval timeout;
    int i, nb;
    volatile int first_call = 1;
    int there_is_a_port = 0;
    error_context_t econ;

    debug_message("Initializations complete.\n\n");
    for (i = 0; i < 5; i++) {
        if (external_port[i].port) {
            debug_message("Accepting connections on port %d.\n",
                    external_port[i].port);
            there_is_a_port = 1;
        }
    }

    if (!there_is_a_port)
        debug_message("No external ports specified.\n");

    init_user_conn();   /* initialize user connection socket */
#ifdef SIGHUP
    signal(SIGHUP, startshutdownMudOS);
#endif
    clear_state();
    save_context(&econ);
    if (SETJMP(econ.context))
        restore_context(&econ);
    if (!t_flag && first_call) {
        first_call = 0;
        call_heart_beat();
    }

    while (1) {
        /* Has to be cleared if we jumped out of process_user_command() */
        current_interactive = 0;
        set_eval(max_cost);

        if (obj_list_replace || obj_list_destruct)
            remove_destructed_objects();

        /*
         * shut down MudOS if MudOS_is_being_shut_down is set.
         */
        if (MudOS_is_being_shut_down)
            shutdownMudOS(0);
        if (slow_shut_down_to_do) {
            int tmp = slow_shut_down_to_do;

            slow_shut_down_to_do = 0;
            slow_shut_down(tmp);
        }
        /*
         * select
         */
        make_selectmasks();
        timeout.tv_sec = 1;
        timeout.tv_usec = 0;
#ifndef hpux
        nb = select(FD_SETSIZE, &readmask, &writemask, (fd_set *) 0, &timeout);
#else
        nb = select(FD_SETSIZE, (int *) &readmask, (int *) &writemask,
                (int *) 0, &timeout);
#endif
        /*
         * process I/O if necessary.
         */
        if (nb > 0) {
            process_io();
        }
        /*
         * process user commands.
         */
        for (i = 0; process_user_command() && i < max_users; i++)
            ;

        /*
         * call outs
         */
        call_out();
#ifdef PACKAGE_ASYNC
        check_reqs();
#endif
    }
}       /* backend() */
示例#8
0
void backend()
{
    struct timeval timeout;
    int i, nb;
    volatile int first_call = 1;
    int there_is_a_port = 0;
    error_context_t econ;

    debug_message("Initializations complete.\n\n");
    for (i = 0; i < 5; i++) {
	if (external_port[i].port) {
	    debug_message("Accepting connections on port %d.\n",
		    external_port[i].port);
	    there_is_a_port = 1;
	}
    }

    if (!there_is_a_port)
	debug_message("No external ports specified.\n");

    init_user_conn();		/* initialize user connection socket */
#ifdef SIGHUP
    signal(SIGHUP, startshutdownMudOS);
#endif
    clear_state();
    save_context(&econ);
    if (SETJMP(econ.context))
	restore_context(&econ);
    if (!t_flag && first_call) {
	first_call = 0;
	call_heart_beat();
    }

    while (1) {	
	/* Has to be cleared if we jumped out of process_user_command() */
	current_interactive = 0;
	eval_cost = max_cost;

	if (obj_list_replace || obj_list_destruct)
	    remove_destructed_objects();

	/*
	 * shut down MudOS if MudOS_is_being_shut_down is set.
	 */
	if (MudOS_is_being_shut_down)
	    shutdownMudOS(0);
	if (slow_shut_down_to_do) {
	    int tmp = slow_shut_down_to_do;

	    slow_shut_down_to_do = 0;
	    slow_shut_down(tmp);
	}
	/*
	 * select
	 */
	make_selectmasks();
	if (heart_beat_flag) {	/* use zero timeout if a heartbeat is
				 * pending. */
	    timeout.tv_sec = 0;	/* this should avoid problems with longjmp's
				 * too */
	    timeout.tv_usec = 0;
	} else {
	    /*
	     * not using infinite timeout so that we'll have insurance in the
	     * unlikely event a heartbeat happens between now and the
	     * select(). Note that SIGALRMs (for heartbeats) do make select()
	     * drop through. (Except on Windows)
	     */
#ifdef WIN32
	    timeout.tv_sec = HEARTBEAT_INTERVAL/1000000;
	    timeout.tv_usec = HEARTBEAT_INTERVAL%1000000;
#else
	    timeout.tv_sec = 60;
	    timeout.tv_usec = 0;
#endif
	}
#ifndef hpux
	nb = select(FD_SETSIZE, &readmask, &writemask, (fd_set *) 0, &timeout);
#else
	nb = select(FD_SETSIZE, (int *) &readmask, (int *) &writemask,
		    (int *) 0, &timeout);
#endif
	/*
	 * process I/O if necessary.
	 */
	if (nb > 0) {
	    process_io();
	}
	/*
	 * process user commands.
	 */
	for (i = 0; process_user_command() && i < max_users; i++)
	    ;

	/*
	 * call heartbeat if appropriate.
	 */
	if (heart_beat_flag)
	    call_heart_beat();
    }
}				/* backend() */