Exemple #1
0
/// Read data from the network
int RASocket::handle_input(ACE_HANDLE)
{
    DEBUG_LOG("RASocket::handle_input");
    if (closing_)
    {
        sLog.outError("Called RASocket::handle_input with closing_ = true");
        return -1;
    }

    size_t readBytes = peer().recv(inputBuffer + inputBufferLen, RA_BUFF_SIZE - inputBufferLen - 1);

    if (readBytes <= 0)
    {
        DEBUG_LOG("read " SIZEFMTD " bytes in RASocket::handle_input", readBytes);
        return -1;
    }

    ///- Discard data after line break or line feed
    bool gotenter = false;
    for (; readBytes > 0 ; --readBytes)
    {
        char c = inputBuffer[inputBufferLen];
        if (c == '\r' || c == '\n')
        {
            gotenter = true;
            break;
        }
        ++inputBufferLen;
    }

    if (gotenter)
    {
        inputBuffer[inputBufferLen] = 0;
        inputBufferLen = 0;
        switch (stage)
        {
                /// <ul> <li> If the input is '<username>'
            case NONE:
            {
                std::string szLogin = inputBuffer;

                accId = sAccountMgr.GetId(szLogin);

                ///- If the user is not found, deny access
                if (!accId)
                {
                    sendf("-No such user.\r\n");
                    sLog.outRALog("User %s does not exist.", szLogin.c_str());
                    if (bSecure)
                    {
                        handle_output();
                        return -1;
                    }
                    sendf("\r\n");
                    sendf(sObjectMgr.GetMangosStringForDBCLocale(LANG_RA_USER));
                    break;
                }

                accAccessLevel = sAccountMgr.GetSecurity(accId);

                ///- if gmlevel is too low, deny access
                if (accAccessLevel < iMinLevel)
                {
                    sendf("-Not enough privileges.\r\n");
                    sLog.outRALog("User %s has no privilege.", szLogin.c_str());
                    if (bSecure)
                    {
                        handle_output();
                        return -1;
                    }
                    sendf("\r\n");
                    sendf(sObjectMgr.GetMangosStringForDBCLocale(LANG_RA_USER));
                    break;
                }

                ///- allow by remotely connected admin use console level commands dependent from config setting
                if (accAccessLevel >= SEC_ADMINISTRATOR && !bStricted)
                    { accAccessLevel = SEC_CONSOLE; }

                stage = LG;
                sendf(sObjectMgr.GetMangosStringForDBCLocale(LANG_RA_PASS));
                break;
            }
            ///<li> If the input is '<password>' (and the user already gave his username)
            case LG:
            {
                // login+pass ok
                std::string pw = inputBuffer;

                if (sAccountMgr.CheckPassword(accId, pw))
                {
                    stage = OK;

                    sendf("+Logged in.\r\n");
                    sLog.outRALog("User account %u has logged in.", accId);
                    sendf("mangos>");
                }
                else
                {
                    ///- Else deny access
                    sendf("-Wrong pass.\r\n");
                    sLog.outRALog("User account %u has failed to log in.", accId);
                    if (bSecure)
                    {
                        handle_output();
                        return -1;
                    }
                    sendf("\r\n");
                    sendf(sObjectMgr.GetMangosStringForDBCLocale(LANG_RA_PASS));
                }
                break;
            }
            ///<li> If user is logged, parse and execute the command
            case OK:
                if (strlen(inputBuffer))
                {
                    sLog.outRALog("Got '%s' cmd.", inputBuffer);
                    if (strncmp(inputBuffer, "quit", 4) == 0)
                        { return -1; }
                    else
                    {
                        CliCommandHolder* cmd = new CliCommandHolder(accId, accAccessLevel, this, inputBuffer, &RASocket::zprint, &RASocket::commandFinished);
                        sWorld.QueueCliCommand(cmd);
                        pendingCommands.acquire();
                    }
                }
                else
                    { sendf("mangos>"); }
                break;
                ///</ul>
        };
    }
    // no enter yet? wait for next input...
    return 0;
}
Exemple #2
0
/// RASocket destructor
RASocket::~RASocket()
{
    peer().close();
    sLog.outRALog("Connection was closed.");
}
Exemple #3
0
int WorldSocket::handle_input_missing_data(void)
{
    char buf [4096];

    ACE_Data_Block db(sizeof(buf),
                      ACE_Message_Block::MB_DATA,
                      buf,
                      0,
                      0,
                      ACE_Message_Block::DONT_DELETE,
                      0);

    ACE_Message_Block message_block(&db,
                                    ACE_Message_Block::DONT_DELETE,
                                    0);

    const size_t recv_size = message_block.space();

    const ssize_t n = peer().recv(message_block.wr_ptr(),
                                  recv_size);

    if (n <= 0)
        return (int)n;

    message_block.wr_ptr(n);

    while (message_block.length() > 0)
    {
        if (m_Header.space() > 0)
        {
            // need to receive the header
            const size_t to_header = (message_block.length() > m_Header.space() ? m_Header.space() : message_block.length());
            m_Header.copy(message_block.rd_ptr(), to_header);
            message_block.rd_ptr(to_header);

            if (m_Header.space() > 0)
            {
                // Couldn't receive the whole header this time.
                MANGOS_ASSERT(message_block.length() == 0);
                errno = EWOULDBLOCK;
                return -1;
            }

            // We just received nice new header
            if (handle_input_header() == -1)
            {
                MANGOS_ASSERT((errno != EWOULDBLOCK) && (errno != EAGAIN));
                return -1;
            }
        }

        // Its possible on some error situations that this happens
        // for example on closing when epoll receives more chunked data and stuff
        // hope this is not hack ,as proper m_RecvWPct is asserted around
        if (!m_RecvWPct)
        {
            sLog.outError("Forcing close on input m_RecvWPct = NULL");
            errno = EINVAL;
            return -1;
        }

        // We have full read header, now check the data payload
        if (m_RecvPct.space() > 0)
        {
            // need more data in the payload
            const size_t to_data = (message_block.length() > m_RecvPct.space() ? m_RecvPct.space() : message_block.length());
            m_RecvPct.copy(message_block.rd_ptr(), to_data);
            message_block.rd_ptr(to_data);

            if (m_RecvPct.space() > 0)
            {
                // Couldn't receive the whole data this time.
                MANGOS_ASSERT(message_block.length() == 0);
                errno = EWOULDBLOCK;
                return -1;
            }
        }

        // just received fresh new payload
        if (handle_input_payload() == -1)
        {
            MANGOS_ASSERT((errno != EWOULDBLOCK) && (errno != EAGAIN));
            return -1;
        }
    }

    return size_t(n) == recv_size ? 1 : 2;
}
Exemple #4
0
int RASocket::send(const std::string& line)
{
    return size_t(peer().send(line.c_str(), line.length())) == line.length() ? 0 : -1;
}
Exemple #5
0
int RASocket::subnegotiate()
{
    char buf[1024];

    ACE_Data_Block db(sizeof (buf),
        ACE_Message_Block::MB_DATA,
        buf,
        0,
        0,
        ACE_Message_Block::DONT_DELETE,
        0);

    ACE_Message_Block message_block(&db,
        ACE_Message_Block::DONT_DELETE,
        0);

    const size_t recv_size = message_block.space();

    // Wait a maximum of 1000ms for negotiation packet - not all telnet clients may send it
    ACE_Time_Value waitTime = ACE_Time_Value(1);
    const ssize_t n = peer().recv(message_block.wr_ptr(),
        recv_size, &waitTime);

    if (n <= 0)
        return int(n);

    if (n >= 1024)
    {
        sLog.outRemote("RASocket::subnegotiate: allocated buffer 1024 bytes was too small for negotiation packet, size: %u", n);
        return -1;
    }

    buf[n] = '\0';

    #ifdef _DEBUG
    for (uint8 i = 0; i < n; )
    {
        uint8 iac = buf[i];
        if (iac == 0xFF)   // "Interpret as Command" (IAC)
        {
            uint8 command = buf[++i];
            std::stringstream ss;
            switch (command)
            {
                case 0xFB:        // WILL
                    ss << "WILL ";
                    break;
                case 0xFC:        // WON'T
                    ss << "WON'T ";
                    break;
                case 0xFD:        // DO
                    ss << "DO ";
                    break;
                case 0xFE:        // DON'T
                    ss << "DON'T ";
                    break;
                default:
                    return -1;      // not allowed
            }

            uint8 param = buf[++i];
            ss << uint32(param);
            sLog.outRemote(ss.str().c_str());
        }
        ++i;
    }
    #endif

    //! Just send back end of subnegotiation packet
    uint8 const reply[2] = {0xFF, 0xF0};
    return peer().send(reply, 2);
}
void ChannelMembersWidget::onMembers() {
	if (auto channel = peer()->asChannel()) {
		Ui::show(Box<MembersBox>(channel, MembersFilter::Recent));
	}
}
 int open(void *msg){
   assert(0 == strcmp((char*)msg, MSG_1));
   peer().send_n(MSG_2, strlen(MSG_2));
   peer().close();
   return 0;
 }
Exemple #8
0
	ACE_HANDLE get_handle() const
	{
		return peer().get_handle();
	}
Exemple #9
0
		if (!value.isEmpty()) {
			values.emplace_back(key, value);
		}
	};
	const auto push = [&](const QByteArray &key, const auto &value) {
		if constexpr (std::is_arithmetic_v<std::decay_t<decltype(value)>>) {
			pushBare(key, NumberToString(value));
		} else {
			const auto wrapped = QByteArray(value);
			if (!wrapped.isEmpty()) {
				pushBare(key, SerializeString(wrapped));
			}
		}
	};
	const auto wrapPeerName = [&](PeerId peerId) {
		return StringAllowNull(peer(peerId).name());
	};
	const auto wrapUserName = [&](int32 userId) {
		return StringAllowNull(user(userId).name());
	};
	const auto pushFrom = [&](const QByteArray &label = "from") {
		if (message.fromId) {
			pushBare(label, wrapUserName(message.fromId));
		}
	};
	const auto pushReplyToMsgId = [&](
			const QByteArray &label = "reply_to_message_id") {
		if (message.replyToMsgId) {
			push(label, message.replyToMsgId);
		}
	};
// Recieve the HTTP Reply
int
ACE_Blob_Reader::receive_reply (void)
{
  ssize_t len;
  char buf [MAX_HEADER_SIZE + 1];
  char *buf_ptr;
  int bytes_read = 0;
  int bytes_left = length_;
  int offset_left = offset_;

  // Receive the first MAX_HEADER_SIZE bytes to be able to strip off the
  // header. Note that we assume that the header will fit into the
  // first MAX_HEADER_SIZE bytes of the transmitted data.
  if ((len = peer ().recv_n (buf, MAX_HEADER_SIZE)) >= 0)
    {
      buf[len] = '\0';

      // Search for the header termination string "\r\n\r\n", or "\n\n". If
      // found, move past it to get to the data portion.
      if ((buf_ptr = ACE_OS::strstr (buf,"\r\n\r\n")) != 0)
        buf_ptr += 4;
      else if ((buf_ptr = ACE_OS::strstr (buf, "\n\n")) != 0)
        buf_ptr += 2;
      else
        buf_ptr = buf;

      // Determine number of data bytes read. This is equal to the
      // total butes read minus number of header bytes.
      bytes_read = (buf + len) - buf_ptr;
    }
  else
    ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "ACE_Blob_Reader::receiveReply():Error while reading header"), -1);

  // ***************************************************************
  // At this point, we have stripped off the header and are ready to
  // process data. buf_ptr points to the data

  // First adjust for offset. There are two cases:
  // (1) The first block of data encountered the offset. In this case
  // we simply increment the buf_ptr by offset.
  // (2) The first block of data did not encounter the offset. That
  // is, the offset needs to go past the number of data bytes already read.
  if (bytes_read > offset_left)
    {
      // The first case is true -- that is offset is less than the
      // data bytes we just read.
      buf_ptr += offset_left;

      // Determine how many data bytes are actually there. This is
      // basically the total number of data bytes we read minus any
      // offset we have.
      int data_bytes = bytes_read - offset_left;

      // Check for the case where the bytes read are enough to fulfill
      // our request (for length bytes). If this is the case, then we
      // don't need to do any extra recvs and can simply return with
      // the data.
      if (data_bytes >= bytes_left)
        {
          // The first block contains enough data to satisfy the
          // length. So copy the data into the message buffer.
          if (mb_->copy (buf_ptr, bytes_left) == -1)
            ACE_ERROR_RETURN ((LM_ERROR, "%p\n",
                               "ACE Blob_Reader::receiveReply():Error copying data into Message_Block"), -1);
          bytecount_ = length_;
          return 0;
        }

      // Copy over all the data bytes into our message buffer.
      if (mb_->copy (buf_ptr, data_bytes) == -1)
        ACE_ERROR_RETURN ((LM_ERROR, "%p\n",
                           "ACE_Blob_Reader::receiveReply():Error copying data into Message_Block" ), -1);

      // Adjust bytes left
      bytes_left -= data_bytes;

      // No more offset left. So set it to zero.
      offset_left = 0;
    }
  else
    {
      // The second case is true -- that is offset is greater than
      // the data bytes we just read.
     offset_left -= bytes_read;
    }

  // If we had any offset left, take care of that.
  while (offset_left > 0)
    {
      // MAX_HEADER_SIZE in which case we should do a receive of
      // offset bytes into a temporary buffer. Otherwise, we should
      // receive MAX_HEADER_SIZE bytes into temporary buffer and
      // decrement offset_left.
      if (offset_left < (int) (sizeof buf))
        len = offset_left;
      else
        len = sizeof buf;
      if (peer().recv_n (buf, len) != len)
        ACE_ERROR_RETURN ((LM_ERROR, "%p\n",
                           "ACE_Blob_Reader::receiveReply():Read error" ),
                          -1);
      offset_left -= len;
    }

  // *****************************************************************
  // At this point we are all set to receive the actual data which the
  // user wants. We have made adjustments for offset and are ready to
  // receive the actual data. Receive the data directly into the
  // message buffer.

  len = peer().recv_n (mb_->wr_ptr (), bytes_left);

  if (len != bytes_left)
    ACE_ERROR_RETURN ((LM_ERROR, "%p\n",
                       "ACE_Blob_Reader::receiveReply():Read error" ), -1);

  // Adjust the message buffer write pointer by number of bytes we
  // received.
  mb_->wr_ptr (len);

  // Set the byte count to number of bytes received
  this->bytecount_ = length_;

  return 0;
}
void cBaseUDP_Server::DisconnectAll(){
	for(cPeer* peer(Peers); peer!=Peers + NumOfPeers; ++peer){// for each peeer
		DisconnectPeerNow(peer);
	}
}
Exemple #12
0
        boost::system::error_code Connector::connect(
            SocketType & peer1, 
            NetName const & netname, 
            boost::system::error_code & ec)
        {
            typedef typename SocketType::protocol_type::socket socket;
            typedef typename socket::endpoint_type endpoint_type;

            socket & peer(peer1); // we should use the real socket type, not the child type

            if (netname.is_digit()) {
                return connect(peer, netname.endpoint(), ec);
            }
            if (!started_) {
                canceled_ = canceled_forever_;
                stat_.reset();
                connect_started_ = false;
                boost::asio::detail::mutex::scoped_lock lock(mutex_);
                if (canceled_) {
                    ec = boost::asio::error::operation_aborted;
                    canceled_ = false;
                } else {
                    lock.unlock();
                    resolver_iterator_ = resolver_.resolve(netname, ec);
                    lock.lock();
                }
                stat_.resolve_time = stat_.elapse();
                if (ec) {
                    return ec;
                } else if (canceled_) {
                    canceled_ = false;
                    return ec = boost::asio::error::operation_aborted;
                }
                started_ = true;
            }
            ResolverIterator end;
            for (; resolver_iterator_ != end; ++resolver_iterator_) {
                if (!connect_started_) {
                    Endpoint const & e = *resolver_iterator_;
                    {
                        boost::asio::detail::mutex::scoped_lock lock(mutex_);
                        if (canceled_) {
                            ec = boost::asio::error::operation_aborted;
                            canceled_ = false;
                        } else {
                            if (peer.is_open()) {
                                peer.close(ec);
                            }
                            boost::asio::socket_base::non_blocking_io cmd1(non_block_);
#ifndef UNDER_CE
                            boost::asio::socket_base::receive_time_out cmd2(time_out_);
#endif
                            ec || peer.open(endpoint_type(e).protocol(), ec) 
                                || peer.io_control(cmd1, ec) 
#ifndef UNDER_CE
                                || peer.set_option(cmd2, ec)
#endif
                                ;
                        }
                    }
                    if (ec) {
                        break;
                    }
                    LOG_TRACE("[connect] try server, ep: " << e.to_string());
                    start_connect(peer, e, ec);
                } else {
                    ec = boost::asio::error::would_block;
                }
                if (ec == boost::asio::error::would_block) {
                    pool_connect(peer, ec);
                }
                if (ec != boost::asio::error::would_block) {
                    if (!ec) {
                        post_connect(peer, ec);
                    } else {
                        boost::system::error_code ec1;
                        post_connect(peer, ec1);
                    }
                }
                if (!ec || ec == boost::asio::error::would_block || canceled_) {
                    break;
                }
                LOG_DEBUG("[connect] failed, ep: " << 
                    resolver_iterator_->to_string() << ",ec: " << ec.message());
            } // for
            if ((!ec || ec == boost::asio::error::would_block) && canceled_) {
                ec = boost::asio::error::operation_aborted;
            }
            if (ec != boost::asio::error::would_block) {
                stat_.connect_time = stat_.elapse();
                started_ = false;
                canceled_ = false;
            }
            return ec;
        }
Exemple #13
0
        boost::system::error_code Connector::connect(
            SocketType & peer1, 
            Endpoint const & endpoint, 
            boost::system::error_code & ec)
        {
            typedef typename SocketType::protocol_type::socket socket;
            typedef typename socket::endpoint_type endpoint_type;

            socket & peer(peer1); // we should use the real socket type, not the child type

            if (!started_) {
                canceled_ = canceled_forever_;
                stat_.reset();
                stat_.resolve_time = 0;
                if (ec) {
                    return ec;
                }
                {
                    boost::asio::detail::mutex::scoped_lock lock(mutex_);
                    if (canceled_) {
                        ec = boost::asio::error::operation_aborted;
                        canceled_ = false;
                    } else if (peer.is_open()) {
                        peer.close(ec);
                    }
                    boost::asio::socket_base::non_blocking_io cmd1(non_block_);
#ifndef UNDER_CE
                    boost::asio::socket_base::receive_time_out cmd2(time_out_);
#endif
                    ec || peer.open(endpoint_type(endpoint).protocol(), ec) 
                        || peer.io_control(cmd1, ec)
#ifndef UNDER_CE
                        || peer.set_option(cmd2, ec)
#endif
                        ;
                    started_ = true;
                }
                connect_started_ = false;
                if (ec)
                    return ec;
                start_connect(peer, endpoint, ec);
            } else {
                ec = boost::asio::error::would_block;
            }
            if (ec == boost::asio::error::would_block) {
                pool_connect(peer, ec);
            }
            if (ec == boost::asio::error::would_block) {
                if (time_out_ && stat_.elapse() > time_out_) {
                    ec = boost::asio::error::timed_out;
                }
            }
            if (ec != boost::asio::error::would_block) {
                if (!ec) {
                    post_connect(peer, ec);
                } else {
                    boost::system::error_code ec1;
                    post_connect(peer, ec1);
                }
                stat_.connect_time = stat_.elapse();
                started_ = false;
                canceled_ = false;
            } 
            return ec;
        }
SPtr<TClntMsg> TClntIfaceMgr::select(unsigned int timeout)
{
    int bufsize=4096;
    static char buf[4096];
    SPtr<TIPv6Addr> peer(new TIPv6Addr());
    int sockid;
    int msgtype;
    int ifaceid;

    sockid = TIfaceMgr::select(timeout, buf, bufsize, peer);

    if (sockid>0) {
        if (bufsize<4) {
            if (buf[0]!=CONTROL_MSG) {
                Log(Warning) << "Received message is too short (" << bufsize
                             << ") bytes." << LogEnd;
            } else {
                Log(Warning) << "Control message received." << LogEnd;
            }
            return 0; // NULL
        }
        msgtype = buf[0];
        SPtr<TClntMsg> ptr;
        SPtr<TIfaceIface> ptrIface;
        ptrIface = this->getIfaceBySocket(sockid);
        ifaceid = ptrIface->getID();
        Log(Debug) << "Received " << bufsize << " bytes on interface " << ptrIface->getName() << "/"
                   << ptrIface->getID() << " (socket=" << sockid << ", addr=" << *peer << "."
                   << ")." << LogEnd;

        switch (msgtype) {
        case ADVERTISE_MSG:
            ptr = new TClntMsgAdvertise(ifaceid,peer,buf,bufsize);
#ifndef MOD_DISABLE_AUTH
            if (!ptr->validateAuthInfo(buf, bufsize, ClntCfgMgr().getAuthAcceptMethods())) {
                    Log(Error) << "Message dropped, authentication validation failed." << LogEnd;
                    return 0;
            }
#endif
            return ptr;
        case SOLICIT_MSG:
        case REQUEST_MSG:
        case CONFIRM_MSG:
        case RENEW_MSG:
        case REBIND_MSG:
        case RELEASE_MSG:
        case DECLINE_MSG:
        case INFORMATION_REQUEST_MSG:
            Log(Warning) << "Illegal message type " << msgtype << " received." << LogEnd;
            return 0; // NULL
        case REPLY_MSG:
            ptr = new TClntMsgReply(ifaceid, peer, buf, bufsize);
#ifndef MOD_DISABLE_AUTH
            if (!ptr->validateAuthInfo(buf, bufsize, ClntCfgMgr().getAuthAcceptMethods())) {
                    Log(Error) << "Message dropped, authentication validation failed." << LogEnd;
                    return 0;
            }
#endif
            return ptr;

        case RECONFIGURE_MSG:
            Log(Warning) << "Reconfigure Message is currently not supported." << LogEnd;
            return 0; // NULL
        case RELAY_FORW_MSG: // those two msgs should not be visible for client
        case RELAY_REPL_MSG:
        default:
            Log(Warning) << "Message type " << msgtype << " is not supposed to "
                         << "be received by client. Check your relay/server configuration." << LogEnd;
            return 0;
        }
    } else {
        return 0;
    }
}
Exemple #15
0
int
OpenDDS::DCPS::TcpConnection::handle_setup_input(ACE_HANDLE /*h*/)
{
  const ssize_t ret = peer().recv(passive_setup_buffer_.wr_ptr(),
                                  passive_setup_buffer_.space(),
                                  &ACE_Time_Value::zero);

  if (ret < 0 && errno == ETIME) {
    return 0;
  }

  VDBG_LVL((LM_DEBUG, "(%P|%t) DBG:   TcpConnection::handle_setup_input %@ "
            "recv returned %b %m.\n", this, ret), 4);

  if (ret <= 0) {
    return -1;
  }

  passive_setup_buffer_.wr_ptr(ret);
  // Parse the setup message: <len><addr><prio>
  // len and prio are network order 32-bit ints
  // addr is a string of length len, including null
  ACE_UINT32 nlen = 0;

  if (passive_setup_buffer_.length() >= sizeof(nlen)) {

    ACE_OS::memcpy(&nlen, passive_setup_buffer_.rd_ptr(), sizeof(nlen));
    passive_setup_buffer_.rd_ptr(sizeof(nlen));
    ACE_UINT32 hlen = ntohl(nlen);
    passive_setup_buffer_.size(hlen + 2 * sizeof(nlen));

    ACE_UINT32 nprio = 0;

    if (passive_setup_buffer_.length() >= hlen + sizeof(nprio)) {

      const std::string bufstr(passive_setup_buffer_.rd_ptr());
      const NetworkAddress network_order_address(bufstr);
      network_order_address.to_addr(remote_address_);

      ACE_OS::memcpy(&nprio, passive_setup_buffer_.rd_ptr() + hlen, sizeof(nprio));
      transport_priority_ = ntohl(nprio);

      passive_setup_buffer_.reset();
      passive_setup_ = false;

      VDBG((LM_DEBUG, "(%P|%t) DBG:   TcpConnection::handle_setup_input "
            "%@ %C:%d->%C:%d, priority==%d, reconnect_state = %d\n", this,
            remote_address_.get_host_addr(), remote_address_.get_port_number(),
            local_address_.get_host_addr(), local_address_.get_port_number(),
            transport_priority_, reconnect_state_));

      // remove from reactor, normal recv strategy setup will add us back
      if (reactor()->remove_handler(this, READ_MASK | DONT_CALL) == -1) {
        VDBG((LM_DEBUG, "(%P|%t) DBG:   TcpConnection::handle_setup_input "
              "remove_handler failed %m.\n"));
      }

      const TcpConnection_rch self(this, false);

      transport_during_setup_->passive_connection(remote_address_, self);
      transport_during_setup_ = 0;
      connected_ = true;

      return 0;
    }
  }

  passive_setup_buffer_.rd_ptr(passive_setup_buffer_.base());

  return 0;
}