示例#1
0
/**
 * [Server only]
 * Handle a new connection from a client. Set up connection details and
 * initialize sequence numbers.
 *
 * pkt: The SYN segment from the client.
 * returns: The conn_t associated with the new connection.
 */
conn_t *tcp_new_connection(char *pkt) { ASSERT_SERVER_ONLY;
  /* Ignore if too many clients are connected. */
  if (num_connected >= MAX_NUM_CLIENTS) {
    fprintf(stderr, "[ERROR] Maximum number of clients (%d) reached\n",
            MAX_NUM_CLIENTS);
    return NULL;
  }
  num_connected++;

  iphdr_t *ip_hdr = (iphdr_t *) pkt;
  tcphdr_t *syn = (tcphdr_t *) (pkt + IP_HDR_SIZE);

  /* Set up connection details and add to list of connections. */
  conn_t *conn = calloc(sizeof(conn_t), 1);
  conn_setup(conn, ntohl(ip_hdr->saddr), ntohs(syn->th_sport), unix_socket);
  conn->their_init_seqno = ntohl(syn->th_seq);
  conn->ackno = conn->their_init_seqno + 1;
  conn_add(conn);

  /* Send a SYN-ACK to the client. */
  send_synack(conn);

  /* Get window size of the client. */
  ctcp_cfg->send_window = ntohs(syn->window);
  ctcp_config_t *config_copy = calloc(sizeof(ctcp_config_t), 1);
  memcpy(config_copy, ctcp_cfg, sizeof(ctcp_config_t));

  /* Student code. */
  ctcp_state_t *state = ctcp_init(conn, config_copy);
  conn->state = state;

  fprintf(stderr, "[INFO] Client connected\n");
  return conn;
}
void
MulticastSession::syn_received(const Message_Block_Ptr& control)
{
  if (this->active_) return; // pub send syn, then doesn't receive them.

  const TransportHeader& header =
    this->link_->receive_strategy()->received_header();

  // Not from the remote peer for this session.
  if (this->remote_peer_ != header.source_) return;

  Serializer serializer(control.get(), header.swap_bytes());

  MulticastPeer local_peer;
  serializer >> local_peer; // sent as remote_peer

  // Ignore sample if not destined for us:
  if (local_peer != this->link_->local_peer()) return;

  VDBG_LVL((LM_DEBUG, "(%P|%t) MulticastSession[%C]::syn_received "
                    "local %#08x%08x remote %#08x%08x\n",
                    this->link()->config()->name().c_str(),
                    (unsigned int)(this->link()->local_peer() >> 32),
                    (unsigned int) this->link()->local_peer(),
                    (unsigned int)(this->remote_peer_ >> 32),
                    (unsigned int) this->remote_peer_), 2);

  {
    ACE_GUARD(ACE_SYNCH_MUTEX, guard, this->ack_lock_);

    if (!this->acked_) {
      this->acked_ = true;
      syn_hook(header.sequence_);
    }
  }

  // MULTICAST_SYN control samples are always positively
  // acknowledged by a matching remote peer:
  send_synack();

  this->link_->transport()->passive_connection(this->link_->local_peer(), this->remote_peer_);

}
示例#3
0
void
ReliableSession::syn_received(ACE_Message_Block* control)
{
  if (this->active_) return; // pub send syn, then doesn't receive them.

  const TransportHeader& header =
    this->link_->receive_strategy()->received_header();

  // Not from the remote peer for this session.
  if (this->remote_peer_ != header.source_) return;

  Serializer serializer(control, header.swap_bytes());

  MulticastPeer local_peer;
  serializer >> local_peer; // sent as remote_peer

  // Ignore sample if not destined for us:
  if (local_peer != this->link_->local_peer()) return;

  {
    ACE_GUARD(ACE_SYNCH_MUTEX,
              guard,
              this->ack_lock_);

    if (!this->acked_) {
      this->acked_ = true;

      // Establish a baseline for detecting reception gaps:
      this->nak_sequence_.reset(header.sequence_);
    }
  }

  // MULTICAST_SYN control samples are always positively
  // acknowledged by a matching remote peer:
  send_synack();
}