Exemplo n.º 1
0
/** Segment arrived */
void tcp_as_segment_arrived(tcp_sockpair_t *sp, tcp_segment_t *seg)
{
	tcp_conn_t *conn;

	log_msg(LOG_DEFAULT, LVL_DEBUG, "tcp_as_segment_arrived(f:(%x,%u), l:(%x,%u))",
	    sp->foreign.addr.ipv4, sp->foreign.port,
	    sp->local.addr.ipv4, sp->local.port);

	conn = tcp_conn_find_ref(sp);
	if (conn == NULL) {
		log_msg(LOG_DEFAULT, LVL_WARN, "No connection found.");
		tcp_unexpected_segment(sp, seg);
		return;
	}

	fibril_mutex_lock(&conn->lock);

	if (conn->cstate == st_closed) {
		log_msg(LOG_DEFAULT, LVL_WARN, "Connection is closed.");
		tcp_unexpected_segment(sp, seg);
		fibril_mutex_unlock(&conn->lock);
		tcp_conn_delref(conn);
		return;
	}

	if (conn->ident.foreign.addr.ipv4 == TCP_IPV4_ANY)
		conn->ident.foreign.addr.ipv4 = sp->foreign.addr.ipv4;
	if (conn->ident.foreign.port == TCP_PORT_ANY)
		conn->ident.foreign.port = sp->foreign.port;
	if (conn->ident.local.addr.ipv4 == TCP_IPV4_ANY)
		conn->ident.local.addr.ipv4 = sp->local.addr.ipv4;

	tcp_conn_segment_arrived(conn, seg);

	fibril_mutex_unlock(&conn->lock);
	tcp_conn_delref(conn);
}
Exemplo n.º 2
0
/** Segment arrived */
void tcp_as_segment_arrived(inet_ep2_t *epp, tcp_segment_t *seg)
{
	tcp_conn_t *conn;

	log_msg(LOG_DEFAULT, LVL_DEBUG,
	    "tcp_as_segment_arrived(f:(%u), l:(%u))",
	    epp->remote.port, epp->local.port);

	conn = tcp_conn_find_ref(epp);
	if (conn == NULL) {
		log_msg(LOG_DEFAULT, LVL_WARN, "No connection found.");
		tcp_unexpected_segment(epp, seg);
		return;
	}

	tcp_conn_segment_arrived(conn, epp, seg);
	tcp_conn_delref(conn);
}
Exemplo n.º 3
0
/** Segment arrived on a connection.
 *
 * @param conn		Connection
 * @param epp		Endpoint pair on which segment was received
 * @param seg		Segment
 */
void tcp_conn_segment_arrived(tcp_conn_t *conn, inet_ep2_t *epp,
    tcp_segment_t *seg)
{
	inet_ep2_t aepp;
	inet_ep2_t oldepp;
	int rc;

	log_msg(LOG_DEFAULT, LVL_DEBUG, "%s: tcp_conn_segment_arrived(%p)",
	    conn->name, seg);

	tcp_conn_lock(conn);

	if (conn->cstate == st_closed) {
		log_msg(LOG_DEFAULT, LVL_WARN, "Connection is closed.");
		tcp_unexpected_segment(epp, seg);
		tcp_conn_unlock(conn);
		return;
	}

	if (inet_addr_is_any(&conn->ident.remote.addr) ||
	    conn->ident.remote.port == inet_port_any ||
	    inet_addr_is_any(&conn->ident.local.addr)) {

		log_msg(LOG_DEFAULT, LVL_DEBUG2, "tcp_conn_segment_arrived: "
		    "Changing connection ID, updating amap.");
		oldepp = conn->ident;

		/* Need to remove and re-insert connection with new identity */
		fibril_mutex_lock(&conn_list_lock);

		if (inet_addr_is_any(&conn->ident.remote.addr))
			conn->ident.remote.addr = epp->remote.addr;

		if (conn->ident.remote.port == inet_port_any)
			conn->ident.remote.port = epp->remote.port;

		if (inet_addr_is_any(&conn->ident.local.addr))
			conn->ident.local.addr = epp->local.addr;

		rc = amap_insert(amap, &conn->ident, conn, af_allow_system, &aepp);
		if (rc != EOK) {
			assert(rc != EEXIST);
			assert(rc == ENOMEM);
			log_msg(LOG_DEFAULT, LVL_ERROR, "Out of memory.");
			fibril_mutex_unlock(&conn_list_lock);
			tcp_conn_unlock(conn);
			return;
		}

		amap_remove(amap, &oldepp);
		fibril_mutex_unlock(&conn_list_lock);

		conn->name = (char *) "a";
	}

	switch (conn->cstate) {
	case st_listen:
		tcp_conn_sa_listen(conn, seg);
		break;
	case st_syn_sent:
		tcp_conn_sa_syn_sent(conn, seg);
		break;
	case st_syn_received:
	case st_established:
	case st_fin_wait_1:
	case st_fin_wait_2:
	case st_close_wait:
	case st_closing:
	case st_last_ack:
	case st_time_wait:
		/* Process segments in order of sequence number */
		tcp_conn_sa_queue(conn, seg);
		break;
	case st_closed:
		log_msg(LOG_DEFAULT, LVL_DEBUG, "state=%d", (int) conn->cstate);
		assert(false);
	}

	tcp_conn_unlock(conn);
}