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; }
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; }
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; }