示例#1
0
文件: list_file.c 项目: roughi/my_ftp
int				try_to_connect(struct s_static_client *br)
{
  set_sock_options(br->pasv);
  if (connect(br->pasv, (struct sockaddr *) &(br->sin_pasv),
	       sizeof(struct sockaddr)) == -1)
    {
      xclose(br->pasv);
      br->pasv = reopen_socket();
      (br->sin_pasv).sin_addr.s_addr = (br->sin).sin_addr.s_addr;
      if (connect(br->pasv, (struct sockaddr *) &(br->sin_pasv),
		   sizeof(struct sockaddr)) == -1)
	{
	  reset_sock_options(br->pasv);
	  my_putstr("ERROR : Impossible to open dataconnection to try connect\n");
	  return (-1);
	}
    }
  reset_sock_options(br->pasv);
  return (0);
}
int
OpenDDS::DCPS::SimpleTcpConnection::open(void* arg)
{
  DBG_ENTRY_LVL("SimpleTcpConnection","open",6);

  // A safety check - This should not happen since the is_connector_
  // defaults to true and open() is called after the ACE_Aceptor
  // creates this new svc handler.
  if (this->is_connector_ == false)
  	{
  	  return -1;
  	}

  // This connection object represents the acceptor side.
  this->is_connector_ = false;

  // The passed-in arg is really the acceptor object that created this
  // SimpleTcpConnection object, and is also the caller of this open()
  // method.  We need to cast the arg to the SimpleTcpAcceptor* type.
  SimpleTcpAcceptor* acceptor = ACE_static_cast(SimpleTcpAcceptor*,arg);

  if (acceptor == 0)
    {
      // The cast failed.
      ACE_ERROR_RETURN((LM_ERROR,
                        "(%P|%t) ERROR: Failed to cast void* arg to "
                        "SimpleTcpAcceptor* type.\n"),
                       -1);
    }

  // Now we need to ask the SimpleTcpAcceptor object to provide us with
  // a pointer to the SimpleTcpTransport object that "owns" the acceptor.
  SimpleTcpTransport_rch transport = acceptor->transport();

  if (transport.is_nil())
    {
      // The acceptor gave us a nil transport (smart) pointer.
      ACE_ERROR_RETURN((LM_ERROR,
                        "(%P|%t) ERROR: Acceptor's transport is nil.\n"),
                       -1);
    }

  SimpleTcpConfiguration* tcp_config = acceptor->get_configuration();

  // Keep a "copy" of the reference to SimpleTcpConfiguration object
  // for ourselves.
  tcp_config->_add_ref ();
  this->tcp_config_ = tcp_config;

  set_sock_options(this->tcp_config_.in ());

  // We expect that the active side of the connection (the remote side
  // in this case) will supply its listening ACE_INET_Addr as the first
  // message it sends to the socket.  This is a one-way connection
  // establishment protocol message.

  ACE_UINT32 nlen = 0;
  if (this->peer().recv_n(&nlen,
                          sizeof(ACE_UINT32)) == -1)
    {
         ACE_ERROR_RETURN((LM_ERROR,
                        "(%P|%t) ERROR: Unable to receive the length of address string "
                        "from the remote (active) side of the connection."
                        " %p\n", "recv_n"),
                         -1);
    }
 
  ACE_UINT32 len = ntohl(nlen);

  char * buf = new char [len];

  if (this->peer().recv_n(buf,
                          len) == -1)
    {
         ACE_ERROR_RETURN((LM_ERROR,
                        "(%P|%t) ERROR: Unable to receive the address string "
                        "from the remote (active) side of the connection."
                        " %p\n", "recv_n"),
                         -1);
    }

  NetworkAddress network_order_address(buf);

  network_order_address.to_addr(this->remote_address_);

  delete[] buf;


//MJM: vvv CONNECTION ESTABLISHMENT CHANGES vvv

//MJM: Add code to send a response to the other side that the
//MJM: connection is ready to receive at this point.  It may be
//MJM: necessary to do this higher in the layers to make sure that we
//MJM: really are ready to receive.

//MJM: This is the only really tricky bit, since I have not really
//MJM: investigated enough to know where the connection is considered
//MJM: complete on this end.  I think that it will be when the datalink
//MJM: is placed in all the containers.

//MJM: This is also where this end needs to call back the
//MJM: TransportInterface method that will eventually signal() the
//MJM: wait()ing add_associations() call.  It may not be necessary on
//MJM: this (passive) to actually perform the wait() and signal()
//MJM: operations.  There is enough information in the
//MJM: add_associations() call to differentiate the cases.

//MJM: ^^^ CONNECTION ESTABLISHMENT CHANGES ^^^


  VDBG((LM_DEBUG, "(%P|%t) DBG:   "
    "SimpleTcpConnection::open %X %s:%d->%s:%d reconnect_state = %d\n", this,
    this->remote_address_.get_host_addr (), this->remote_address_.get_port_number (),
    this->local_address_.get_host_addr (), this->local_address_.get_port_number (),
    this->reconnect_state_));

  // Now it is time to announce (and give) ourselves to the
  // SimpleTcpTransport object.
  transport->passive_connection(this->remote_address_,this);

  this->connected_ = true;

  return 0;
}
int
OpenDDS::DCPS::SimpleTcpConnection::active_establishment
                                    (const ACE_INET_Addr& remote_address,
                                     const ACE_INET_Addr& local_address,
                                     SimpleTcpConfiguration_rch tcp_config)
{
  DBG_ENTRY_LVL("SimpleTcpConnection","active_establishment",6);

  // Cache these values for reconnecting.
  this->remote_address_ = remote_address;
  this->local_address_ = local_address;
  this->tcp_config_ = tcp_config;

  // Safty check - This should not happen since is_connector_ defaults to
  // true and the role in a connection connector is not changed when reconnecting.
  if (this->is_connector_ == false)
    {
      ACE_ERROR_RETURN((LM_ERROR,
                        "(%P|%t) ERROR: Failed to connect because it's previouly an acceptor.\n"),
                        -1);
    }

  if (this->shutdown_)
    return -1;

  // Now use a connector object to establish the connection.
  ACE_SOCK_Connector connector;
  if (connector.connect(this->peer(), remote_address) != 0)
    {
      ACE_ERROR_RETURN((LM_ERROR,
                        "(%P|%t) ERROR: Failed to connect. %p\n", "connect"),
                       -1);
    }
  else
    {
      this->connected_ = true;
    }

  set_sock_options(tcp_config.in ());

  // In order to complete the connection establishment from the active
  // side, we need to tell the remote side about our local_address.
  // It will use that as an "identifier" of sorts.  To the other
  // (passive) side, our local_address that we send here will be known
  // as the remote_address.
  ACE_UINT32 len = tcp_config_->local_address_str_.length () + 1;

  ACE_UINT32 nlen = htonl(len);

  if (this->peer().send_n( &nlen,
                           sizeof (ACE_UINT32)) == -1)
    {
      // TBD later - Anything we are supposed to do to close the connection.
      ACE_ERROR_RETURN((LM_ERROR,
                        "(%P|%t) ERROR: Unable to send address string length to "
                        "the passive side to complete the active connection "
                        "establishment.\n"),
                       -1);
    }

  if (this->peer().send_n( tcp_config_->local_address_str_.c_str(),
                           len)  == -1)
    {
      // TBD later - Anything we are supposed to do to close the connection.
      ACE_ERROR_RETURN((LM_ERROR,
                        "(%P|%t) ERROR: Unable to send our address to "
                        "the passive side to complete the active connection "
                        "establishment.\n"),
                       -1);
    }


//MJM: vvv CONNECTION ESTABLISHMENT CHANGES vvv

//MJM: Add code to receive a response from the other side that the
//MJM: connection is ready to receive at this point.  Block until it is
//MJM: received.  Then call the method in the TransportInterface that
//MJM: the add_associations() call is wait()ing on.

//MJM: ^^^ CONNECTION ESTABLISHMENT CHANGES ^^^

  return 0;
}
示例#4
0
int
OpenDDS::DCPS::TcpConnection::active_establishment(bool initiate_connect)
{
  DBG_ENTRY_LVL("TcpConnection","active_establishment",6);

  // Safety check - This should not happen since is_connector_ defaults to
  // true and the role in a connection connector is not changed when reconnecting.
  if (this->is_connector_ == false) {
    ACE_ERROR_RETURN((LM_ERROR,
                      "(%P|%t) ERROR: Failed to connect because it's previously an acceptor.\n"),
                     -1);
  }

  if (this->shutdown_)
    return -1;

  // Now use a connector object to establish the connection.
  ACE_SOCK_Connector connector;

  if (initiate_connect && connector.connect(this->peer(), remote_address_) != 0) {

    std::ostringstream os;
    this->tcp_config_->dump(os);

    ACE_ERROR_RETURN((LM_ERROR,
                      ACE_TEXT("(%P|%t) ERROR: Failed to connect. %p\n%C"),
                      ACE_TEXT("connect"), os.str().c_str()),
                     -1);

  } else {
    this->connected_ = true;
    const std::string remote_host = this->remote_address_.get_host_addr();
    VDBG((LM_DEBUG, "(%P|%t) DBG:   active_establishment(%C:%d->%C:%d)\n",
          this->local_address_.get_host_addr(), this->local_address_.get_port_number(),
          remote_host.c_str(), this->remote_address_.get_port_number()));
  }

  // Set the DiffServ codepoint according to the priority value.
  DirectPriorityMapper mapper(this->transport_priority_);
  this->link_->set_dscp_codepoint(mapper.codepoint(), this->peer());

  set_sock_options(tcp_config_.in());

  // In order to complete the connection establishment from the active
  // side, we need to tell the remote side about our public address.
  // It will use that as an "identifier" of sorts.  To the other
  // (passive) side, our local_address that we send here will be known
  // as the remote_address.
  std::string address = tcp_config_->get_public_address();
  ACE_UINT32 len = static_cast<ACE_UINT32>(address.length()) + 1;

  ACE_UINT32 nlen = htonl(len);

  if (this->peer().send_n(&nlen,
                          sizeof(ACE_UINT32)) == -1) {
    // TBD later - Anything we are supposed to do to close the connection.
    ACE_ERROR_RETURN((LM_ERROR,
                      "(%P|%t) ERROR: Unable to send address string length to "
                      "the passive side to complete the active connection "
                      "establishment.\n"),
                     -1);
  }

  if (this->peer().send_n(address.c_str(), len)  == -1) {
    // TBD later - Anything we are supposed to do to close the connection.
    ACE_ERROR_RETURN((LM_ERROR,
                      "(%P|%t) ERROR: Unable to send our address to "
                      "the passive side to complete the active connection "
                      "establishment.\n"),
                     -1);
  }

  ACE_UINT32 npriority = htonl(this->transport_priority_);

  if (this->peer().send_n(&npriority, sizeof(ACE_UINT32)) == -1) {
    // TBD later - Anything we are supposed to do to close the connection.
    ACE_ERROR_RETURN((LM_ERROR,
                      "(%P|%t) ERROR: Unable to send publication priority to "
                      "the passive side to complete the active connection "
                      "establishment.\n"),
                     -1);
  }

  return 0;
}
示例#5
0
int
OpenDDS::DCPS::TcpConnection::open(void* arg)
{
  DBG_ENTRY_LVL("TcpConnection","open",6);

  if (is_connector_) {

    VDBG_LVL((LM_DEBUG, "(%P|%t) DBG:   TcpConnection::open active.\n"), 2);
    // Take over the refcount from TcpTransport::connect_datalink().
    const TcpConnection_rch self(this);
    const TcpTransport_rch transport = link_->get_transport_impl();

    const bool is_loop(local_address_ == remote_address_);
    const PriorityKey key(transport_priority_, remote_address_,
                          is_loop, false /* !active */);

    int active_open_ = active_open();

    int connect_tcp_datalink_ = transport->connect_tcp_datalink(link_, self);

    if (active_open_ == -1 || connect_tcp_datalink_ == -1) {
      // if (active_open() == -1 ||
      //       transport->connect_tcp_datalink(link_, self) == -1) {

      transport->async_connect_failed(key);

      return -1;
    }

    return 0;
  }

  // The passed-in arg is really the acceptor object that created this
  // TcpConnection object, and is also the caller of this open()
  // method.  We need to cast the arg to the TcpAcceptor* type.
  TcpAcceptor* acceptor = static_cast<TcpAcceptor*>(arg);

  if (acceptor == 0) {
    // The cast failed.
    ACE_ERROR_RETURN((LM_ERROR,
                      ACE_TEXT("(%P|%t) ERROR: TcpConnection::open() - ")
                      ACE_TEXT("failed to cast void* arg to ")
                      ACE_TEXT("TcpAcceptor* type.\n")),
                     -1);
  }

  // Now we need to ask the TcpAcceptor object to provide us with
  // a pointer to the TcpTransport object that "owns" the acceptor.
  TcpTransport_rch transport = acceptor->transport();

  if (transport.is_nil()) {
    // The acceptor gave us a nil transport (smart) pointer.
    ACE_ERROR_RETURN((LM_ERROR,
                      ACE_TEXT("(%P|%t) ERROR: TcpConnection::open() - ")
                      ACE_TEXT("acceptor's transport is nil.\n")),
                     -1);
  }

  TcpInst* tcp_config = acceptor->get_configuration();

  // Keep a "copy" of the reference to TcpInst object
  // for ourselves.
  tcp_config->_add_ref();
  tcp_config_ = tcp_config;
  local_address_ = tcp_config_->local_address_;

  set_sock_options(tcp_config_.in());

  // We expect that the active side of the connection (the remote side
  // in this case) will supply its listening ACE_INET_Addr as the first
  // message it sends to the socket.  This is a one-way connection
  // establishment protocol message.
  passive_setup_ = true;
  transport_during_setup_ = transport;
  passive_setup_buffer_.size(sizeof(ACE_UINT32));

  if (reactor()->register_handler(this, READ_MASK) == -1) {
    ACE_ERROR_RETURN((LM_ERROR,
                      ACE_TEXT("(%P|%t) ERROR: TcpConnection::open() - ")
                      ACE_TEXT("unable to register with the reactor.%p\n"),
                      ACE_TEXT("register_handler")),
                     -1);
  }

  VDBG_LVL((LM_DEBUG, "(%P|%t) DBG:   TcpConnection::open passive handle=%d.\n",
            int(get_handle())), 2);

  return 0;
}