/** * [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_); }
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(); }