示例#1
0
文件: socks.c 项目: GNUnet/gnunet
/**
 * Run a SOCKS5 handshake on an open but unused TCP connection.
 *
 * @param ih SOCKS5 handshake, consumed here.
 * @param c open unused connection, consumed here.
 * @return Connection handle that becomes usable when the SOCKS5 handshake completes.
 */
struct GNUNET_CONNECTION_Handle *
GNUNET_SOCKS_run_handshake(struct GNUNET_SOCKS_Handshake *ih,
                            struct GNUNET_CONNECTION_Handle *c)
{
  ih->socks5_connection=c;
  ih->target_connection = GNUNET_CONNECTION_create_proxied_from_handshake (c);
  register_sender (ih);

  return ih->target_connection;
}
示例#2
0
文件: socks.c 项目: GNUnet/gnunet
/**
 * Register SOCKS5 handshake sender
 *
 * @param cls closure (SOCKS handshake)
 * @param size number of bytes available in @a buf
 * @param buf where the callee should write the message
 * @return number of bytes written to @a buf
 */
size_t
transmit_ready (void *cls,
                size_t size,
                void *buf)
{
  struct GNUNET_SOCKS_Handshake * ih = cls;

  /* connection.c has many routines that call us with buf == NULL :
   * signal_transmit_error() - DNS, etc. active
   *   connect_fail_continuation()
   *     connect_probe_continuation() - timeout
   *     try_connect_using_address() - DNS failure/timeout
   *     transmit_timeout() - retry failed?
   * GNUNET_CONNECTION_notify_transmit_ready() can schedule :
   *   transmit_timeout() - DNS still working
   *   connect_error() - DNS done but no socket?
   * transmit_ready() - scheduler shutdown or timeout, or signal_transmit_error()
   * We'd need to dig into the scheduler to guess at the reason, as
   * connection.c tells us nothing itself, but mostly its timouts.
   * Initially, we'll simply ignore this and leave massive timeouts, but
   * maybe that should change for error handling pruposes.  It appears that
   * successful operations, including DNS resolution, do not use this.  */
  if (NULL == buf)
  {
    if (0 == ih->step)
    {
      LOG (GNUNET_ERROR_TYPE_WARNING,
	   "Timeout contacting SOCKS server, retrying indefinitely, but probably hopeless.\n");
      register_sender (ih);
    }
    else
    {
      LOG (GNUNET_ERROR_TYPE_ERROR,
	   "Timeout during mid SOCKS handshake (step %u), probably not a SOCKS server.\n",
	   ih->step);
      GNUNET_break (0);
    }
    return 0;
  }

  GNUNET_assert (1024 >= size && size > 0);
  GNUNET_assert (SOCKS5_step_done > ih->step && ih->step >= 0);
  unsigned char * b = ih->outstep[ih->step];
  unsigned char * e = ih->outstep[ih->step+1];
  GNUNET_assert (e <= &ih->outbuf[1024]);
  unsigned l = e - b;
  GNUNET_assert (size >= l && l >= 0);
  GNUNET_memcpy(buf, b, l);
  register_reciever (ih, register_reciever_wants(ih));
  return l;
}
示例#3
0
vrpn_File_Connection::vrpn_File_Connection (const char * station_name,
                         const char * local_in_logfile_name,
                         const char * local_out_logfile_name) :
    vrpn_Connection (local_in_logfile_name, local_out_logfile_name, NULL, NULL),
    d_controllerId (register_sender("vrpn File Controller")),
    d_set_replay_rate_type(register_message_type("vrpn_File set_replay_rate")),
    d_reset_type (register_message_type("vrpn_File reset")),
    d_play_to_time_type (register_message_type("vrpn_File play_to_time")),
    d_fileName (NULL),
    d_file (NULL),
    d_logHead (NULL),
    d_logTail (NULL),
    d_currentLogEntry (NULL),
    d_preload(vrpn_FILE_CONNECTIONS_SHOULD_PRELOAD),
    d_accumulate(vrpn_FILE_CONNECTIONS_SHOULD_ACCUMULATE)
{
    // Because we are a file connection, our status should be CONNECTED
    // Later set this to BROKEN if there is a problem opening/reading the file.
    if (d_endpoints[0] == NULL) {
      fprintf(stderr,"vrpn_File_Connection::vrpn_File_Connection(): NULL zeroeth endpoint\n");
    } else {
      connectionStatus = CONNECTED;
      d_endpoints[0]->status = CONNECTED;
    }

    // If we are preloading, then we must accumulate messages.
    if (d_preload) {
      d_accumulate = true;
    }

    // These are handlers for messages that may be sent from a
    // vrpn_File_Controller object that may attach itself to us.
    register_handler(d_set_replay_rate_type, handle_set_replay_rate,
                     this, d_controllerId);
    register_handler(d_reset_type, handle_reset, this, d_controllerId);
    register_handler(d_play_to_time_type, handle_play_to_time,
                     this, d_controllerId);

    // necessary to initialize properly in mainloop()
    d_last_time.tv_usec = d_last_time.tv_sec = 0;
    
    d_fileName = vrpn_copy_file_name(station_name);
    if (!d_fileName) {
        fprintf(stderr, "vrpn_File_Connection:  Out of memory!\n");
        connectionStatus = BROKEN;
        return;
    }

    d_file = fopen(d_fileName, "rb");
    if (!d_file) {
        fprintf(stderr, "vrpn_File_Connection:  "
                "Could not open file \"%s\".\n", d_fileName);
        connectionStatus = BROKEN;
        return;
    }

    // Read the cookie from the file.  It will print an error message if it
    // can't read it, so we just pass the broken status on up the chain.
    if (read_cookie() < 0) {
	connectionStatus = BROKEN;
	return;
    }

    // If we are supposed to preload the entire file into memory buffers,
    // then keep reading until we get to the end.  Otherwise, just read the
    // first message to get things going.
    if (d_preload) {
      while (!read_entry()) { }
    } else {
      read_entry();
    }

    // Initialize the "current message" pointer to the first log-file
    // entry that was read, and set the start time for the file and
    // the current time to the one in this message.
    if (d_logHead) {
      d_currentLogEntry = d_logHead;
      d_startEntry = d_logHead;
      d_start_time = d_startEntry->data.msg_time;  
      d_time = d_start_time;
      d_earliest_user_time.tv_sec = d_earliest_user_time.tv_usec = 0;
      d_earliest_user_time_valid = false;
      d_highest_user_time.tv_sec = d_highest_user_time.tv_usec = 0;
      d_highest_user_time_valid = false;
    } else {
      fprintf(stderr, "vrpn_File_Connection: Can't read first message\n");
      connectionStatus = BROKEN;
      return;
    }

    // This is useful to play the initial system messages
    // (the sender/type ones) automatically.  These might not be
    // time synched so if we don't play them automatically they
    // can mess up playback if their timestamps are later then
    // the first user message.
    if (vrpn_FILE_CONNECTIONS_SHOULD_SKIP_TO_USER_MESSAGES) {
	play_to_user_message();
	if (d_currentLogEntry) {
	    d_start_time = d_currentLogEntry->data.msg_time;
	    d_time = d_start_time;
	}
    }

    // Add this to the list of known connections.
    vrpn_ConnectionManager::instance().addConnection(this, station_name);
}
示例#4
0
文件: socks.c 项目: GNUnet/gnunet
/**
 * Read one step in the SOCKS5 handshake.
 *
 * @param ih SOCKS5 Handshake
 */
void
SOCKS5_handshake_step (struct GNUNET_SOCKS_Handshake *ih)
{
  unsigned char * b = ih->instart;
  size_t available = ih->inend - b;

  int want = register_reciever_wants(ih);
  if (available < want) {
    register_reciever (ih, want - available);
    return;
  }
  GNUNET_assert (SOCKS5_step_done > ih->step && ih->step >= 0);
  switch (ih->step) {
    case SOCKS5_step_greet:  /* SOCKS5 server's greeting */
      if (b[0] != 5)
      {
        LOG (GNUNET_ERROR_TYPE_ERROR,
             "Not a SOCKS5 server\n");
        GNUNET_assert (0);
      }
      switch (b[1]) {
        case SOCKS5_AUTH_NOAUTH:
          ih->step=SOCKS5_step_cmd;  /* no authentication to do */
          break;
        case SOCKS5_AUTH_USERPASS:
          ih->step=SOCKS5_step_auth;
          break;
        case SOCKS5_AUTH_REJECT:
          LOG (GNUNET_ERROR_TYPE_ERROR,
               "No authentication method accepted\n");
          return;
        default:
          LOG (GNUNET_ERROR_TYPE_ERROR,
               "Not a SOCKS5 server / Nonsensical authentication\n");
          return;
      }
      b += 2;
      break;
    case SOCKS5_step_auth:  /* SOCKS5 server's responce to authentication */
      if (b[1] != 0)
      {
        LOG (GNUNET_ERROR_TYPE_ERROR,
             "SOCKS5 authentication failed\n");
        GNUNET_assert (0);
      }
      ih->step=SOCKS5_step_cmd;
      b += 2;
      break;
    case SOCKS5_step_cmd:  /* SOCKS5 server's responce to command */
      if (b[0] != 5)
      {
        LOG (GNUNET_ERROR_TYPE_ERROR,
             "SOCKS5 protocol error\n");
        GNUNET_assert (0);
      }
      if (0 != b[1]) {
        LOG (GNUNET_ERROR_TYPE_ERROR,
             "SOCKS5 connection error : %s\n",
             SOCKS5_REP_names(b[1]));
        return;
      }
      b += 3;
      /* There is no reason to verify host and port afaik. */
      switch (*(b++)) {
        case 1: /* IPv4 */
          b += sizeof(struct in_addr);  /* 4 */
          break;
        case 4: /* IPv6 */
          b += sizeof(struct in6_addr);  /* 16 */
          break;
        case 3: /* hostname */
          b += *b;
          break;
      }
      b += 2;  /* port */
      if (b > ih->inend) {
        register_reciever (ih, b - ih->inend);
        return;
      }
      ih->step = SOCKS5_step_done;
      LOG (GNUNET_ERROR_TYPE_DEBUG,
           "SOCKS5 server : %s\n",
           SOCKS5_REP_names(b[1]));
      ih->instart = b;
      SOCKS5_handshake_done (ih);
      return;
    case SOCKS5_step_done:
      GNUNET_assert (0);
  }
  ih->instart = b;
  /* Do not reschedule the sender unless we're done reading.
   * I imagine this lets us avoid ever cancelling the transmit handle. */
  register_sender (ih);
}