天天看點

SCTP協定源碼分析--多歸屬特性multi-homed(一)

SCTP協定有一個重要的特點,即Multi-homed(多歸屬),這是與TCP協定不同的顯著地方之一,是對TCP協定的重大改進,充分利用了多條路由皆可承載資料流的特點,保證了實體網絡級的備援。

Multi-homed SCTP的直接表現就是有多個transport(即通路path),即到對端多個IP位址的path(通路)。一般來說有一條primary transport(主通路),其它的就是alternate transport(備用通路)。

SCTP的每條path實際上就是一條路由,而SCTP查找路由是根據destination address(目标位址)來決定,是以path的管理依賴于OSI L3(IP層)的路由緩存。而且,每條path的source address(源端位址)由路由決定,是以多條path的source address可能是本端的同一個IP address,盡管本端也許綁定了多個IP address。

先來看看與多path密切相關的IP位址清單的管理。 

一.    Manage address list

主要管理兩個連結清單,即對端的peer_addr清單(實際上是path連結清單)和本地的bind_addr清單,都采用了核心的資料結構雙向連結清單list_head。同時加上counter便于管理。這些位址表用雙向連結清單list_head儲存,而多個association卻用哈希表,此處不詳述。

1. 到對端的path連結清單

連結清單:asoc->peer.transport_addr_list

數量:asoc->peer.transport_count

主path的對端IP:assoc->peer.primary_addr

比如在函數sctp_seq_dump_remote_addrs中要列印對端的所有IP位址。

list_for_each_entry(transport, &assoc->peer.transport_addr_list,
			transports) {
		addr = &transport->ipaddr;
		af = sctp_get_af_specific(addr->sa.sa_family);
		af->seq_dump_addr(seq, addr);
	}

           

管理連結清單的函數:sctp_assoc_add_peer和sctp_assoc_rm_peer

比如添加一個新的path到偶聯的path連結清單:

/* Add a transport address to an association.  */
    struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
					   const union sctp_addr *addr,
					   const gfp_t gfp,
					   const int peer_state)
    {
	struct sctp_transport *peer;
    //。。。(略)
	peer = sctp_transport_new(net, addr, gfp);
    //。。。(略)
	/* Attach the remote transport to our asoc.  */
	list_add_tail(&peer->transports, &asoc->peer.transport_addr_list);
	asoc->peer.transport_count++;

	/* If we do not yet have a primary path, set one.  */
	if (!asoc->peer.primary_path) {
		sctp_assoc_set_primary(asoc, peer);
		asoc->peer.retran_path = peer;
	}
	if (asoc->peer.active_path == asoc->peer.retran_path &&
	    peer->state != SCTP_UNCONFIRMED) {
		asoc->peer.retran_path = peer;
	}

	return peer;
    }

           

2. 本端綁定的addr_entry連結清單

連結清單:asoc->base.bind_addr.address_list

數量:asoc->base.bind_addr.address_count          //目前沒有,可以考慮增加

主path的本端IP:asoc->peer.primary_path.saddr

比如,在擷取路由函數sctp_v4_get_dst中,需周遊本端綁定位址連結清單:

bp = &asoc->base.bind_addr;
	if (dst) {
		/* Walk through the bind address list and look for a bind
		 * address that matches the source address of the returned dst.
		 */
		sctp_v4_dst_saddr(&dst_saddr, fl4, htons(bp->port));
		rcu_read_lock();
		list_for_each_entry_rcu(laddr, &bp->address_list, list) {
			if (!laddr->valid || (laddr->state == SCTP_ADDR_DEL) ||
			    (laddr->state != SCTP_ADDR_SRC &&
			    !asoc->src_out_of_asoc_ok))
				continue;
			if (sctp_v4_cmp_addr(&dst_saddr, &laddr->a))
				goto out_unlock;
		}
		rcu_read_unlock();
        //。。。(略)
	}
           

再比如sctp_seq_dump_local_addrs中要列印本端位址清單,而且會标明primary path:

if (epb->type == SCTP_EP_TYPE_ASSOCIATION) {
	    asoc = sctp_assoc(epb);
	    peer = asoc->peer.primary_path;
	    primary = &peer->saddr;
	}
	list_for_each_entry(laddr, &epb->bind_addr.address_list, list) {
		addr = &laddr->a;
		af = sctp_get_af_specific(addr->sa.sa_family);
		if (primary && af->cmp_addr(addr, primary)) {
			seq_printf(seq, "*");
		}
		af->seq_dump_addr(seq, addr);           //printk
	}
           

下一篇繼續看看transport&association的斷開和恢複管理。 

[原創文章不易,轉載請注明出處連結]

      [ 注本文在此處同步:SCTP協定源碼分析--多歸屬特性multi-homed(一)  ]

繼續閱讀