TCP:伝送制御プロトコル(一)
7336 ワード
関連プロトコル分析はtcp/ipプロトコル学習ノート(8)TCP伝送制御プロトコルを参照する
TCP転送制御ブロックの管理、ソケットオプション、ioctl、エラー処理およびキャッシュ管理は、以下のファイルに関連する.
include/linux/tcp.h TCPセグメントのフォーマット、TCP伝送制御ブロックなどの構造、マクロと関数プロトタイプを定義する
include/net/sock.h基本的な伝送制御ブロック構造、マクロ、関数プロトタイプを定義する
include/net/inet_connection_sock.h接続要求ブロック等の関連インタフェース、マクロ及び関数の定義
include/net/inet_hashtables.h転送制御ブロックを管理するハッシュリストを定義する
net/ipv4/af_inet.cネットワーク層と伝送層インタフェース
net/ipv4/tcp_ipv4.c伝送制御ブロックとネットワーク層との間のインタフェース実装
net/ipv4/tcp.c伝送制御ブロックとアプリケーション層との間のインタフェース実装
net/core/stream.c TCP中流メモリ管理の実現
TCP転送制御ブロック
TCP転送制御ブロックは、接続の確立、データの転送、混雑した制御、および接続の終了を含むTCP全体のプロセスにおいて核心的な役割を果たす.TCP接続の全過程において、以下の3種類のTCP伝送制御ブロックを順次使用する.
1、第1のタイプはtcp_request_sockは、接続を確立する過程で使用され、存在時間が比較的短い
2、第2タイプはtcp_sockは、接続確立後に終了する前に使用され、TCP状態はESTABLISHEDである.このような伝送制御ブロックは、最も長い周期を宣言し、送信および受信セグメントは制御する必要がある.
3、第三のタイプはtcp_timewait_sockは、接続を終了する過程で使用され、その存在過程も比較的短い
inet_connection_sock_af_ops
ネットワーク層に送信されるインタフェース、送信層のsetsockoptインタフェースなど、伝送層に関連する一連の動作セットがカプセル化され、TCPの例はipv 4_である.specific
tcp_options_received
主に受信したTCPオプション情報(タイムスタンプ、SACKなど)を保存するとともに、ウィンドウ拡大係数、ACKなどのエンドツーエンドサポートの特性を示す.
tcp_skb_cb
TCP層は、SKB領域にプライベート情報制御ブロック、すなわちskb_を有するbuff構造のcbメンバーで、TCPはこのフィールドを利用してtcp_を格納します.skb_cb構造.TCP層ではマクロTCP_SKB_CBは、コードの可読性を向上させるために、この情報ブロックへのアクセスを実現する.このプライベート情報制御ブロックに対する付与は、一般に、本層がセグメントまたは送信セグメントを受信する前に行われる.例えばtcp_v4_rcv()はTCP層受信エントリ関数であり、TCPセグメントを受信して必要な検証を行うと、このセグメントのtcp_skb_cbを設定します.一方,送信過程では,TCPセグメントを生成する際,あるいはTCPセグメントをセグメント化する際に設定することが多い.
TCPの初期化
トランスポート層TCPモジュールの初期化関数tcp_Init()IPv 4プロトコルファミリーによる初期化関数inet_Init()呼び出し
TCP転送制御ブロックの管理
TCP転送制御ブロックの作成に成功すると、合理的な管理が必要になります.TCPには複数の状態が存在し、一部の状態が存在する時間は比較的短く、TCPの両端が相互作用する過程で、これらの状態はすぐに別の状態に移行する.対照的に、LISTENとESTABLISHEDの2つの状態は常態である.異なる状態にあるトランスポート制御ブロックを適切に管理およびアクセスするために、TCPは、状態に応じてトランスポート制御ブロックを複数の異なるハッシュリストに格納する.
inet_hashinfo
unsigned int ehash_size;
ehashはehash_というサイズを指すsizeのinet_ehash_bucket構造型のハッシュリストで、LISTEN以外のTCP状態の伝送制御ブロックのハッシュリストを管理する
struct inet_ehash_bucket { struct hlist_nulls_head chain; struct hlist_nulls_head twchain; }; chain、twchainは、転送制御ブロックをリンクするために使用される
struct inet_bind_hashbucket *bhash;
unsigned int bhash_size; サイズはbhash_sizeのbhashハッシュ・リストは、主にバインドされたポートの情報を格納するために使用されます.
struct inet_bind_hashbucket { spinlock_t lock; struct hlist_headchain; };
chainポートバインド情報ブロックの確立
struct inet_listen_hashbucket listening_hash[INET_LHTABLE_SIZE];
LISTEN状態を管理する転送制御ブロックのハッシュリストを格納する
転送制御ブロックの作成に成功すると、転送インタフェースレイヤのhashインタフェースが呼び出され、転送制御ブロックが解放されるまでehashハッシュリストに転送制御ブロックが追加される.TCPではhashインタフェースを実現する関数はtcp_v4_hash().
転送制御ブロックが不要な場合、転送インタフェースレイヤのunhashインタフェースが呼び出され、その転送制御ブロックがehashハッシュリストから削除される.TCPではhashインタフェースを実現する関数はtcp_unhash().
Listenシステム呼び出しを呼び出すと、ソケットインタフェースがLISTEN状態になり、__が呼び出されます.inet_hash()は、listening_に転送制御ブロックを追加するhashハッシュリストでは、リスニング状態にあるソケットインタフェースを迅速に検索できます.
TCP転送制御ブロックの管理、ソケットオプション、ioctl、エラー処理およびキャッシュ管理は、以下のファイルに関連する.
include/linux/tcp.h TCPセグメントのフォーマット、TCP伝送制御ブロックなどの構造、マクロと関数プロトタイプを定義する
include/net/sock.h基本的な伝送制御ブロック構造、マクロ、関数プロトタイプを定義する
include/net/inet_connection_sock.h接続要求ブロック等の関連インタフェース、マクロ及び関数の定義
include/net/inet_hashtables.h転送制御ブロックを管理するハッシュリストを定義する
net/ipv4/af_inet.cネットワーク層と伝送層インタフェース
net/ipv4/tcp_ipv4.c伝送制御ブロックとネットワーク層との間のインタフェース実装
net/ipv4/tcp.c伝送制御ブロックとアプリケーション層との間のインタフェース実装
net/core/stream.c TCP中流メモリ管理の実現
TCP転送制御ブロック
TCP転送制御ブロックは、接続の確立、データの転送、混雑した制御、および接続の終了を含むTCP全体のプロセスにおいて核心的な役割を果たす.TCP接続の全過程において、以下の3種類のTCP伝送制御ブロックを順次使用する.
1、第1のタイプはtcp_request_sockは、接続を確立する過程で使用され、存在時間が比較的短い
2、第2タイプはtcp_sockは、接続確立後に終了する前に使用され、TCP状態はESTABLISHEDである.このような伝送制御ブロックは、最も長い周期を宣言し、送信および受信セグメントは制御する必要がある.
3、第三のタイプはtcp_timewait_sockは、接続を終了する過程で使用され、その存在過程も比較的短い
inet_connection_sock_af_ops
ネットワーク層に送信されるインタフェース、送信層のsetsockoptインタフェースなど、伝送層に関連する一連の動作セットがカプセル化され、TCPの例はipv 4_である.specific
tcp_options_received
主に受信したTCPオプション情報(タイムスタンプ、SACKなど)を保存するとともに、ウィンドウ拡大係数、ACKなどのエンドツーエンドサポートの特性を示す.
tcp_skb_cb
TCP層は、SKB領域にプライベート情報制御ブロック、すなわちskb_を有するbuff構造のcbメンバーで、TCPはこのフィールドを利用してtcp_を格納します.skb_cb構造.TCP層ではマクロTCP_SKB_CBは、コードの可読性を向上させるために、この情報ブロックへのアクセスを実現する.このプライベート情報制御ブロックに対する付与は、一般に、本層がセグメントまたは送信セグメントを受信する前に行われる.例えばtcp_v4_rcv()はTCP層受信エントリ関数であり、TCPセグメントを受信して必要な検証を行うと、このセグメントのtcp_skb_cbを設定します.一方,送信過程では,TCPセグメントを生成する際,あるいはTCPセグメントをセグメント化する際に設定することが多い.
TCPの初期化
トランスポート層TCPモジュールの初期化関数tcp_Init()IPv 4プロトコルファミリーによる初期化関数inet_Init()呼び出し
void __init tcp_init(void)
{
struct sk_buff *skb = NULL;
unsigned long nr_pages, limit;
int i, max_share, cnt;
BUILD_BUG_ON(sizeof(struct tcp_skb_cb) > sizeof(skb->cb));
percpu_counter_init(&tcp_sockets_allocated, 0);
percpu_counter_init(&tcp_orphan_count, 0);
tcp_hashinfo.bind_bucket_cachep =
kmem_cache_create("tcp_bind_bucket",
sizeof(struct inet_bind_bucket), 0,
SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
/* Size and allocate the main established and bind bucket
* hash tables.
*
* The methodology is similar to that of the buffer cache.
*/
tcp_hashinfo.ehash =
alloc_large_system_hash("TCP established",
sizeof(struct inet_ehash_bucket),
thash_entries,
(totalram_pages >= 128 * 1024) ?
13 : 15,
0,
&tcp_hashinfo.ehash_size,
NULL,
thash_entries ? 0 : 512 * 1024);
tcp_hashinfo.ehash_size = 1 << tcp_hashinfo.ehash_size;
for (i = 0; i < tcp_hashinfo.ehash_size; i++) {
INIT_HLIST_NULLS_HEAD(&tcp_hashinfo.ehash[i].chain, i);
INIT_HLIST_NULLS_HEAD(&tcp_hashinfo.ehash[i].twchain, i);
}
if (inet_ehash_locks_alloc(&tcp_hashinfo))
panic("TCP: failed to alloc ehash_locks");
tcp_hashinfo.bhash =
alloc_large_system_hash("TCP bind",
sizeof(struct inet_bind_hashbucket),
tcp_hashinfo.ehash_size,
(totalram_pages >= 128 * 1024) ?
13 : 15,
0,
&tcp_hashinfo.bhash_size,
NULL,
64 * 1024);
tcp_hashinfo.bhash_size = 1 << tcp_hashinfo.bhash_size;
for (i = 0; i < tcp_hashinfo.bhash_size; i++) {
spin_lock_init(&tcp_hashinfo.bhash[i].lock);
INIT_HLIST_HEAD(&tcp_hashinfo.bhash[i].chain);
}
cnt = tcp_hashinfo.ehash_size;
tcp_death_row.sysctl_max_tw_buckets = cnt / 2;
sysctl_tcp_max_orphans = cnt / 2;
sysctl_max_syn_backlog = max(128, cnt / 256);
/* Set the pressure threshold to be a fraction of global memory that
* is up to 1/2 at 256 MB, decreasing toward zero with the amount of
* memory, with a floor of 128 pages, and a ceiling that prevents an
* integer overflow.
*/
nr_pages = totalram_pages - totalhigh_pages;
limit = min(nr_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT);
limit = (limit * (nr_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11);
limit = max(limit, 128UL);
limit = min(limit, INT_MAX * 4UL / 3 / 2);
sysctl_tcp_mem[0] = limit / 4 * 3;
sysctl_tcp_mem[1] = limit;
sysctl_tcp_mem[2] = sysctl_tcp_mem[0] * 2;
/* Set per-socket limits to no more than 1/128 the pressure threshold */
limit = ((unsigned long)sysctl_tcp_mem[1]) << (PAGE_SHIFT - 7);
max_share = min(4UL*1024*1024, limit);
sysctl_tcp_wmem[0] = SK_MEM_QUANTUM;
sysctl_tcp_wmem[1] = 16*1024;
sysctl_tcp_wmem[2] = max(64*1024, max_share);
sysctl_tcp_rmem[0] = SK_MEM_QUANTUM;
sysctl_tcp_rmem[1] = 87380;
sysctl_tcp_rmem[2] = max(87380, max_share);
printk(KERN_INFO "TCP: Hash tables configured "
"(established %d bind %d)
",
tcp_hashinfo.ehash_size, tcp_hashinfo.bhash_size);
tcp_register_congestion_control(&tcp_reno);
}
TCP転送制御ブロックの管理
TCP転送制御ブロックの作成に成功すると、合理的な管理が必要になります.TCPには複数の状態が存在し、一部の状態が存在する時間は比較的短く、TCPの両端が相互作用する過程で、これらの状態はすぐに別の状態に移行する.対照的に、LISTENとESTABLISHEDの2つの状態は常態である.異なる状態にあるトランスポート制御ブロックを適切に管理およびアクセスするために、TCPは、状態に応じてトランスポート制御ブロックを複数の異なるハッシュリストに格納する.
inet_hashinfo
struct inet_hashinfo {
/* This is for sockets with full identity only. Sockets here will
* always be without wildcards and will have the following invariant:
*
* TCP_ESTABLISHED <= sk->sk_state < TCP_CLOSE
*
* TIME_WAIT sockets use a separate chain (twchain).
*/
struct inet_ehash_bucket *ehash;
spinlock_t *ehash_locks;
unsigned int ehash_size;
unsigned int ehash_locks_mask;
/* Ok, let's try this, I give up, we do need a local binding
* TCP hash as well as the others for fast bind/connect.
*/
struct inet_bind_hashbucket *bhash;
unsigned int bhash_size;
/* 4 bytes hole on 64 bit */
struct kmem_cache *bind_bucket_cachep;
/* All the above members are written once at bootup and
* never written again _or_ are predominantly read-access.
*
* Now align to a new cache line as all the following members
* might be often dirty.
*/
/* All sockets in TCP_LISTEN state will be in here. This is the only
* table where wildcard'd TCP sockets can exist. Hash function here
* is just local port number.
*/
struct inet_listen_hashbucket listening_hash[INET_LHTABLE_SIZE]
____cacheline_aligned_in_smp;
atomic_t bsockets;
};
struct inet_ehash_bucket *ehash; unsigned int ehash_size;
ehashはehash_というサイズを指すsizeのinet_ehash_bucket構造型のハッシュリストで、LISTEN以外のTCP状態の伝送制御ブロックのハッシュリストを管理する
struct inet_ehash_bucket { struct hlist_nulls_head chain; struct hlist_nulls_head twchain; }; chain、twchainは、転送制御ブロックをリンクするために使用される
struct inet_bind_hashbucket *bhash;
unsigned int bhash_size; サイズはbhash_sizeのbhashハッシュ・リストは、主にバインドされたポートの情報を格納するために使用されます.
struct inet_bind_hashbucket { spinlock_t lock; struct hlist_headchain; };
chainポートバインド情報ブロックの確立
struct inet_listen_hashbucket listening_hash[INET_LHTABLE_SIZE];
LISTEN状態を管理する転送制御ブロックのハッシュリストを格納する
転送制御ブロックの作成に成功すると、転送インタフェースレイヤのhashインタフェースが呼び出され、転送制御ブロックが解放されるまでehashハッシュリストに転送制御ブロックが追加される.TCPではhashインタフェースを実現する関数はtcp_v4_hash().
転送制御ブロックが不要な場合、転送インタフェースレイヤのunhashインタフェースが呼び出され、その転送制御ブロックがehashハッシュリストから削除される.TCPではhashインタフェースを実現する関数はtcp_unhash().
Listenシステム呼び出しを呼び出すと、ソケットインタフェースがLISTEN状態になり、__が呼び出されます.inet_hash()は、listening_に転送制御ブロックを追加するhashハッシュリストでは、リスニング状態にあるソケットインタフェースを迅速に検索できます.