Exemple #1
0
static void
check_add_routes_action (struct context *c, const bool errors)
{
  do_route (&c->options, c->c1.route_list, c->c1.tuntap, c->plugins, c->c2.es);
  update_time ();
  event_timeout_clear (&c->c2.route_wakeup);
  event_timeout_clear (&c->c2.route_wakeup_expire);
  initialization_sequence_completed (c, errors ? ISC_ERRORS : 0); /* client/p2p --route-delay was defined */
}
Exemple #2
0
/*
 * Things that need to happen immediately after connection initiation should go here.
 */
void
check_connection_established_dowork (struct context *c)
{
  if (event_timeout_trigger (&c->c2.wait_for_connect, &c->c2.timeval, ETT_DEFAULT))
    {
      if (CONNECTION_ESTABLISHED (c))
	{
#if P2MP
	  /* if --pull was specified, send a push request to server */
	  if (c->c2.tls_multi && c->options.pull)
	    {
#ifdef ENABLE_MANAGEMENT
	      if (management)
		{
		  management_set_state (management,
					OPENVPN_STATE_GET_CONFIG,
					NULL,
					0,
					0);
		}
#endif
	      /* send push request in 1 sec */
	      event_timeout_init (&c->c2.push_request_interval, 1, now);
	      reset_coarse_timers (c);
	    }
	  else
#endif
	    {
	      do_up (c, false, 0);
	    }

	  event_timeout_clear (&c->c2.wait_for_connect);
	}
    }
}
Exemple #3
0
void
incoming_push_message (struct context *c, const struct buffer *buffer)
{
  struct gc_arena gc = gc_new ();
  unsigned int option_types_found = 0;
  int status;

  msg (D_PUSH, "PUSH: Received control message: '%s'", sanitize_control_message(BSTR(buffer), &gc));

  status = process_incoming_push_msg (c,
				      buffer,
				      c->options.pull,
				      pull_permission_mask (c),
				      &option_types_found);

  if (status == PUSH_MSG_ERROR)
    msg (D_PUSH_ERRORS, "WARNING: Received bad push/pull message: %s", sanitize_control_message(BSTR(buffer), &gc));
  else if (status == PUSH_MSG_REPLY || status == PUSH_MSG_CONTINUATION)
    {
      c->options.push_option_types_found |= option_types_found;

      if (status == PUSH_MSG_REPLY)
	do_up (c, true, c->options.push_option_types_found ); /* delay bringing tun/tap up until --push parms received from remote */
      event_timeout_clear (&c->c2.push_request_interval);
    }

  gc_free (&gc);
}
Exemple #4
0
void
check_send_occ_load_test_dowork (struct context *c)
{
  if (CONNECTION_ESTABLISHED (c))
    {
      const struct mtu_load_test *entry;

      if (!c->c2.occ_mtu_load_n_tries)
	msg (M_INFO,
	     "NOTE: Beginning empirical MTU test -- results should be available in 3 to 4 minutes.");

      entry = &mtu_load_test_sequence[c->c2.occ_mtu_load_n_tries++];
      if (entry->op >= 0)
	{
	  c->c2.occ_op = entry->op;
	  c->c2.occ_mtu_load_size =
	    EXPANDED_SIZE (&c->c2.frame) + entry->delta;
	}
      else
	{
	  msg (M_INFO,
	       "NOTE: failed to empirically measure MTU (requires " PACKAGE_NAME " 1.5 or higher at other end of connection).");
	  event_timeout_clear (&c->c2.occ_mtu_load_test_interval);
	  c->c2.occ_mtu_load_n_tries = 0;
	}
    }
}
Exemple #5
0
void
check_send_occ_req_dowork (struct context *c)
{
  if (++c->c2.occ_n_tries >= OCC_N_TRIES)
    {
      if (c->options.remote_list)
	/*
	 * No OCC_REPLY from peer after repeated attempts.
	 * Give up.
	 */
	msg (D_SHOW_OCC,
	     "NOTE: failed to obtain options consistency info from peer -- "
	     "this could occur if the remote peer is running a version of "
	     PACKAGE_NAME
	     " before 1.5-beta8 or if there is a network connectivity problem, and will not necessarily prevent "
	     PACKAGE_NAME
             " from running (" counter_format " bytes received from peer, " counter_format
	     " bytes authenticated data channel traffic) -- you can disable the options consistency "
	     "check with --disable-occ.",
             c->c2.link_read_bytes,
             c->c2.link_read_bytes_auth);
      event_timeout_clear (&c->c2.occ_interval);
    }
  else
    {
      c->c2.occ_op = OCC_REQUEST;

      /*
       * If we don't hear back from peer, send another
       * OCC_REQUEST in OCC_INTERVAL_SECONDS.
       */
      event_timeout_reset (&c->c2.occ_interval);
    }
}
Exemple #6
0
void
incoming_push_message(struct context *c, const struct buffer *buffer)
{
    struct gc_arena gc = gc_new();
    unsigned int option_types_found = 0;
    int status;

    msg(D_PUSH, "PUSH: Received control message: '%s'", sanitize_control_message(BSTR(buffer), &gc));

    status = process_incoming_push_msg(c,
                                       buffer,
                                       c->options.pull,
                                       pull_permission_mask(c),
                                       &option_types_found);

    if (status == PUSH_MSG_ERROR)
    {
        msg(D_PUSH_ERRORS, "WARNING: Received bad push/pull message: %s", sanitize_control_message(BSTR(buffer), &gc));
    }
    else if (status == PUSH_MSG_REPLY || status == PUSH_MSG_CONTINUATION)
    {
        c->options.push_option_types_found |= option_types_found;

        /* delay bringing tun/tap up until --push parms received from remote */
        if (status == PUSH_MSG_REPLY)
        {
            if (!do_up(c, true, c->options.push_option_types_found))
            {
                msg(D_PUSH_ERRORS, "Failed to open tun/tap interface");
                goto error;
            }
        }
        event_timeout_clear(&c->c2.push_request_interval);
    }
    else if (status == PUSH_MSG_REQUEST)
    {
        if (c->options.mode == MODE_SERVER)
        {
            struct tls_session *session = &c->c2.tls_multi->session[TM_ACTIVE];
            /* Do not regenerate keys if client send a second push request */
            if (!session->key[KS_PRIMARY].crypto_options.key_ctx_bi.initialized
                && !tls_session_update_crypto_params(session, &c->options,
                                                     &c->c2.frame))
            {
                msg(D_TLS_ERRORS, "TLS Error: initializing data channel failed");
                goto error;
            }
        }
    }

    goto cleanup;
error:
    register_signal(c, SIGUSR1, "process-push-msg-failed");
cleanup:
    gc_free(&gc);
}
Exemple #7
0
void
process_explicit_exit_notification_timer_wakeup(struct context *c)
{
    if (event_timeout_trigger(&c->c2.explicit_exit_notification_interval,
                              &c->c2.timeval,
                              ETT_DEFAULT))
    {
        ASSERT(c->c2.explicit_exit_notification_time_wait && c->options.ce.explicit_exit_notification);
        if (now >= c->c2.explicit_exit_notification_time_wait + c->options.ce.explicit_exit_notification)
        {
            event_timeout_clear(&c->c2.explicit_exit_notification_interval);
            c->sig->signal_received = SIGTERM;
            c->sig->signal_text = "exit-with-notification";
        }
        else
        {
            c->c2.occ_op = OCC_EXIT;
        }
    }
}
Exemple #8
0
void
process_received_occ_msg (struct context *c)
{
  ASSERT (buf_advance (&c->c2.buf, OCC_STRING_SIZE));
  switch (buf_read_u8 (&c->c2.buf))
    {
    case OCC_REQUEST:
      dmsg (D_PACKET_CONTENT, "RECEIVED OCC_REQUEST");
      c->c2.occ_op = OCC_REPLY;
      break;

    case OCC_MTU_REQUEST:
      dmsg (D_PACKET_CONTENT, "RECEIVED OCC_MTU_REQUEST");
      c->c2.occ_op = OCC_MTU_REPLY;
      break;

    case OCC_MTU_LOAD_REQUEST:
      dmsg (D_PACKET_CONTENT, "RECEIVED OCC_MTU_LOAD_REQUEST");
      c->c2.occ_mtu_load_size = buf_read_u16 (&c->c2.buf);
      if (c->c2.occ_mtu_load_size >= 0)
	c->c2.occ_op = OCC_MTU_LOAD;
      break;

    case OCC_REPLY:
      dmsg (D_PACKET_CONTENT, "RECEIVED OCC_REPLY");
      if (c->options.occ && !TLS_MODE (c) && c->c2.options_string_remote)
	{
	  if (!options_cmp_equal_safe ((char *) BPTR (&c->c2.buf),
				       c->c2.options_string_remote,
				       c->c2.buf.len))
	    {
	      options_warning_safe ((char *) BPTR (&c->c2.buf),
				    c->c2.options_string_remote,
				    c->c2.buf.len);
	    }
	}
      event_timeout_clear (&c->c2.occ_interval);
      break;

    case OCC_MTU_REPLY:
      dmsg (D_PACKET_CONTENT, "RECEIVED OCC_MTU_REPLY");
      c->c2.max_recv_size_remote = buf_read_u16 (&c->c2.buf);
      c->c2.max_send_size_remote = buf_read_u16 (&c->c2.buf);
      if (c->options.mtu_test
	  && c->c2.max_recv_size_remote > 0
	  && c->c2.max_send_size_remote > 0)
	{
	  msg (M_INFO, "NOTE: Empirical MTU test completed [Tried,Actual] local->remote=[%d,%d] remote->local=[%d,%d]",
	       c->c2.max_send_size_local,
	       c->c2.max_recv_size_remote,
	       c->c2.max_send_size_remote,
	       c->c2.max_recv_size_local);
	  if (!c->options.fragment
	      && c->options.proto == PROTO_UDPv4
	      && c->c2.max_send_size_local > TUN_MTU_MIN
	      && (c->c2.max_recv_size_remote < c->c2.max_send_size_local
		  || c->c2.max_recv_size_local < c->c2.max_send_size_remote))
	    msg (M_INFO, "NOTE: This connection is unable to accomodate a UDP packet size of %d. Consider using --fragment or --mssfix options as a workaround.",
		 c->c2.max_send_size_local);
	}
      event_timeout_clear (&c->c2.occ_mtu_load_test_interval);
      break;

    case OCC_EXIT:
      dmsg (D_PACKET_CONTENT, "RECEIVED OCC_EXIT");
      c->sig->signal_received = SIGTERM;
      c->sig->signal_text = "remote-exit";
      break;
    }
  c->c2.buf.len = 0; /* don't pass packet on */
}
Exemple #9
0
struct status_output *
status_open(const char *filename,
            const int refresh_freq,
            const int msglevel,
            const struct virtual_output *vout,
            const unsigned int flags)
{
    struct status_output *so = NULL;
    if (filename || msglevel >= 0 || vout)
    {
        ALLOC_OBJ_CLEAR(so, struct status_output);
        so->flags = flags;
        so->msglevel = msglevel;
        so->vout = vout;
        so->fd = -1;
        buf_reset(&so->read_buf);
        event_timeout_clear(&so->et);
        if (filename)
        {
            switch (so->flags)
            {
                case STATUS_OUTPUT_WRITE:
                    so->fd = platform_open(filename,
                                           O_CREAT | O_TRUNC | O_WRONLY,
                                           S_IRUSR | S_IWUSR);
                    break;

                case STATUS_OUTPUT_READ:
                    so->fd = platform_open(filename,
                                           O_RDONLY,
                                           S_IRUSR | S_IWUSR);
                    break;

                case STATUS_OUTPUT_READ|STATUS_OUTPUT_WRITE:
                    so->fd = platform_open(filename,
                                           O_CREAT | O_RDWR,
                                           S_IRUSR | S_IWUSR);
                    break;

                default:
                    ASSERT(0);
            }
            if (so->fd >= 0)
            {
                so->filename = string_alloc(filename, NULL);
                set_cloexec(so->fd);

                /* allocate read buffer */
                if (so->flags & STATUS_OUTPUT_READ)
                {
                    so->read_buf = alloc_buf(512);
                }
            }
            else
            {
                msg(M_WARN, "Note: cannot open %s for %s", filename, print_status_mode(so->flags));
                so->errors = true;
            }
        }
        else
        {
            so->flags = STATUS_OUTPUT_WRITE;
        }

        if ((so->flags & STATUS_OUTPUT_WRITE) && refresh_freq > 0)
        {
            event_timeout_init(&so->et, refresh_freq, 0);
        }
    }
    return so;
}